From 376e03d5f5db13a70489234bbc10c4e68fcf1f30 Mon Sep 17 00:00:00 2001 From: Philip Zingmark <112874974+Phillezi@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:15:03 +0200 Subject: [PATCH 01/36] Update README.md Fix storage directory typo? --- scripts/local/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/local/README.md b/scripts/local/README.md index 8e239a3a..baecbaba 100644 --- a/scripts/local/README.md +++ b/scripts/local/README.md @@ -43,7 +43,7 @@ The following services will be installed in the Kubernetes cluster: ### Storage -The setup script creates a local directory `$HOME/go-deploy-storage/go-deploy-dev` to store the data for the NFS server. +The setup script creates a local directory `$HOME/go-deploy-data/go-deploy-dev` to store the data for the NFS server. This is done using a mix of manually provisioning the storage and using the NFS CSI driver to create a PersistentVolumeClaim. From c4fbae22ee1466461ed28694c22d878955979a27 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Fri, 13 Sep 2024 01:34:30 +0200 Subject: [PATCH 02/36] update go module name --- cmd/flag.go | 18 ++--- cmd/server.go | 18 ++--- go.mod | 2 +- main.go | 2 +- models/config/config.go | 4 +- models/config/config_convert.go | 2 +- models/config/helpers.go | 2 +- models/model/api_key.go | 2 +- models/model/deployment_convert.go | 6 +- models/model/deployment_subsystems.go | 4 +- models/model/discover.go | 2 +- models/model/gpu_group.go | 4 +- models/model/gpu_lease.go | 2 +- models/model/gpu_lease_convert.go | 4 +- models/model/host.go | 2 +- models/model/job_convert.go | 4 +- models/model/notification.go | 2 +- models/model/quotas.go | 2 +- models/model/resource_migration.go | 2 +- models/model/resource_migration_params.go | 2 +- models/model/role.go | 2 +- models/model/sm_dto.go | 2 +- models/model/sm_subsystems.go | 2 +- models/model/team_convert.go | 4 +- models/model/user_convert.go | 4 +- models/model/vm_convert.go | 6 +- models/model/vm_subsystems.go | 2 +- models/model/worker_status.go | 2 +- pkg/auth/gin_keycloak.go | 4 +- pkg/config/config.go | 12 +-- pkg/db/base.go | 2 +- pkg/db/db.go | 2 +- pkg/db/key_value/client.go | 4 +- pkg/db/message_queue/client.go | 4 +- pkg/db/migrate/migrate.go | 6 +- pkg/db/mongo.go | 4 +- pkg/db/redis.go | 4 +- .../base_clients/activity_resource_client.go | 4 +- .../resources/base_clients/resource_client.go | 2 +- .../timestamped_resource_client.go | 2 +- pkg/db/resources/deployment_repo/client.go | 6 +- pkg/db/resources/deployment_repo/db.go | 12 +-- pkg/db/resources/event_repo/client.go | 6 +- pkg/db/resources/event_repo/db.go | 2 +- pkg/db/resources/gpu_group_repo/client.go | 6 +- pkg/db/resources/gpu_group_repo/db.go | 6 +- pkg/db/resources/gpu_lease_repo/client.go | 6 +- pkg/db/resources/gpu_lease_repo/db.go | 4 +- pkg/db/resources/host_repo/client.go | 6 +- pkg/db/resources/host_repo/db.go | 2 +- pkg/db/resources/job_repo/client.go | 6 +- pkg/db/resources/job_repo/db.go | 4 +- pkg/db/resources/notification_repo/client.go | 6 +- pkg/db/resources/notification_repo/db.go | 2 +- .../resource_migration_repo/client.go | 6 +- .../resources/resource_migration_repo/db.go | 4 +- pkg/db/resources/sm_repo/client.go | 6 +- pkg/db/resources/sm_repo/db.go | 4 +- .../system_capacities_repo/client.go | 6 +- .../resources/system_gpu_info_repo/client.go | 6 +- pkg/db/resources/system_stats_repo/client.go | 6 +- pkg/db/resources/system_status_repo/client.go | 6 +- pkg/db/resources/team_repo/client.go | 6 +- pkg/db/resources/team_repo/db.go | 4 +- pkg/db/resources/user_repo/client.go | 6 +- pkg/db/resources/user_repo/db.go | 6 +- pkg/db/resources/vm_port_repo/client.go | 6 +- pkg/db/resources/vm_port_repo/db.go | 2 +- pkg/db/resources/vm_repo/client.go | 8 +- pkg/db/resources/vm_repo/db.go | 12 +-- pkg/db/resources/worker_status_repo/client.go | 6 +- pkg/imp/harbor/harbor/client.go | 2 +- pkg/imp/harbor/harbor/client_test.go | 8 +- pkg/imp/harbor/harbor/test/server.go | 2 +- .../client/artifact/add_label_parameters.go | 2 +- .../client/artifact/add_label_responses.go | 2 +- .../artifact/copy_artifact_responses.go | 2 +- .../client/artifact/create_tag_parameters.go | 2 +- .../client/artifact/create_tag_responses.go | 2 +- .../artifact/delete_artifact_responses.go | 2 +- .../client/artifact/delete_tag_responses.go | 2 +- .../client/artifact/get_addition_responses.go | 2 +- .../client/artifact/get_artifact_responses.go | 2 +- .../get_vulnerabilities_addition_responses.go | 2 +- .../artifact/list_accessories_responses.go | 2 +- .../artifact/list_artifacts_responses.go | 2 +- .../client/artifact/list_tags_responses.go | 2 +- .../client/artifact/remove_label_responses.go | 2 +- .../auditlog/list_audit_logs_responses.go | 2 +- .../configure/get_configurations_responses.go | 2 +- .../configure/get_internalconfig_responses.go | 2 +- .../update_configurations_parameters.go | 2 +- .../gc/create_gc_schedule_parameters.go | 2 +- .../client/gc/create_gc_schedule_responses.go | 2 +- .../client/gc/get_gc_history_responses.go | 2 +- .../v2.0/client/gc/get_gc_log_responses.go | 2 +- .../sdk/v2.0/client/gc/get_gc_responses.go | 2 +- .../client/gc/get_gc_schedule_responses.go | 2 +- .../sdk/v2.0/client/gc/stop_gc_responses.go | 2 +- .../gc/update_gc_schedule_parameters.go | 2 +- .../client/gc/update_gc_schedule_responses.go | 2 +- .../sdk/v2.0/client/harbor_api_client.go | 78 +++++++++---------- .../client/health/get_health_responses.go | 2 +- .../v2.0/client/icon/get_icon_responses.go | 2 +- .../immutable/create_immu_rule_parameters.go | 2 +- .../immutable/create_immu_rule_responses.go | 2 +- .../immutable/delete_immu_rule_responses.go | 2 +- .../immutable/list_immu_rules_responses.go | 2 +- .../immutable/update_immu_rule_parameters.go | 2 +- .../immutable/update_immu_rule_responses.go | 2 +- .../action_get_job_log_responses.go | 2 +- .../action_pending_jobs_parameters.go | 2 +- .../action_pending_jobs_responses.go | 2 +- .../jobservice/get_worker_pools_responses.go | 2 +- .../jobservice/get_workers_responses.go | 2 +- .../jobservice/list_job_queues_responses.go | 2 +- .../jobservice/stop_running_job_responses.go | 2 +- .../client/label/create_label_parameters.go | 2 +- .../client/label/create_label_responses.go | 2 +- .../client/label/delete_label_responses.go | 2 +- .../client/label/get_label_by_id_responses.go | 2 +- .../client/label/list_labels_responses.go | 2 +- .../client/label/update_label_parameters.go | 2 +- .../client/label/update_label_responses.go | 2 +- .../ldap/import_ldap_user_parameters.go | 2 +- .../client/ldap/import_ldap_user_responses.go | 2 +- .../v2.0/client/ldap/ping_ldap_parameters.go | 2 +- .../v2.0/client/ldap/ping_ldap_responses.go | 2 +- .../ldap/search_ldap_group_responses.go | 2 +- .../client/ldap/search_ldap_user_responses.go | 2 +- .../create_project_member_parameters.go | 2 +- .../member/create_project_member_responses.go | 2 +- .../member/delete_project_member_responses.go | 2 +- .../member/get_project_member_responses.go | 2 +- .../member/list_project_members_responses.go | 2 +- .../update_project_member_parameters.go | 2 +- .../member/update_project_member_responses.go | 2 +- .../v2.0/client/oidc/ping_oidc_responses.go | 2 +- .../permissions/get_permissions_responses.go | 2 +- .../preheat/create_instance_parameters.go | 2 +- .../preheat/create_instance_responses.go | 2 +- .../preheat/create_policy_parameters.go | 2 +- .../client/preheat/create_policy_responses.go | 2 +- .../preheat/delete_instance_responses.go | 2 +- .../client/preheat/delete_policy_responses.go | 2 +- .../client/preheat/get_execution_responses.go | 2 +- .../client/preheat/get_instance_responses.go | 2 +- .../client/preheat/get_policy_responses.go | 2 +- .../preheat/get_preheat_log_responses.go | 2 +- .../preheat/list_executions_responses.go | 2 +- .../preheat/list_instances_responses.go | 2 +- .../client/preheat/list_policies_responses.go | 2 +- .../preheat/list_providers_responses.go | 2 +- .../list_providers_under_project_responses.go | 2 +- .../client/preheat/list_tasks_responses.go | 2 +- .../preheat/manual_preheat_parameters.go | 2 +- .../preheat/manual_preheat_responses.go | 2 +- .../preheat/ping_instances_parameters.go | 2 +- .../preheat/ping_instances_responses.go | 2 +- .../preheat/stop_execution_parameters.go | 2 +- .../preheat/stop_execution_responses.go | 2 +- .../preheat/update_instance_parameters.go | 2 +- .../preheat/update_instance_responses.go | 2 +- .../preheat/update_policy_parameters.go | 2 +- .../client/preheat/update_policy_responses.go | 2 +- .../project/create_project_parameters.go | 2 +- .../project/create_project_responses.go | 2 +- .../project/delete_project_responses.go | 2 +- .../v2.0/client/project/get_logs_responses.go | 2 +- .../get_project_deletable_responses.go | 2 +- .../client/project/get_project_responses.go | 2 +- .../project/get_project_summary_responses.go | 2 +- .../get_scanner_of_project_responses.go | 2 +- .../client/project/head_project_responses.go | 2 +- .../client/project/list_projects_responses.go | 2 +- ...scanner_candidates_of_project_responses.go | 2 +- .../set_scanner_of_project_parameters.go | 2 +- .../set_scanner_of_project_responses.go | 2 +- .../project/update_project_parameters.go | 2 +- .../project/update_project_responses.go | 2 +- .../add_project_metadatas_responses.go | 2 +- .../delete_project_metadata_responses.go | 2 +- .../get_project_metadata_responses.go | 2 +- .../list_project_metadatas_responses.go | 2 +- .../update_project_metadata_responses.go | 2 +- .../purge/create_purge_schedule_parameters.go | 2 +- .../purge/create_purge_schedule_responses.go | 2 +- .../purge/get_purge_history_responses.go | 2 +- .../purge/get_purge_job_log_responses.go | 2 +- .../client/purge/get_purge_job_responses.go | 2 +- .../purge/get_purge_schedule_responses.go | 2 +- .../v2.0/client/purge/stop_purge_responses.go | 2 +- .../purge/update_purge_schedule_parameters.go | 2 +- .../purge/update_purge_schedule_responses.go | 2 +- .../v2.0/client/quota/get_quota_responses.go | 2 +- .../client/quota/list_quotas_responses.go | 2 +- .../client/quota/update_quota_parameters.go | 2 +- .../client/quota/update_quota_responses.go | 2 +- .../registry/create_registry_parameters.go | 2 +- .../registry/create_registry_responses.go | 2 +- .../registry/delete_registry_responses.go | 2 +- .../registry/get_registry_info_responses.go | 2 +- .../client/registry/get_registry_responses.go | 2 +- .../registry/list_registries_responses.go | 2 +- .../list_registry_provider_infos_responses.go | 2 +- .../list_registry_provider_types_responses.go | 2 +- .../registry/ping_registry_parameters.go | 2 +- .../registry/ping_registry_responses.go | 2 +- .../registry/update_registry_parameters.go | 2 +- .../registry/update_registry_responses.go | 2 +- .../create_replication_policy_parameters.go | 2 +- .../create_replication_policy_responses.go | 2 +- .../delete_replication_policy_responses.go | 2 +- .../get_replication_execution_responses.go | 2 +- .../get_replication_log_responses.go | 2 +- .../get_replication_policy_responses.go | 2 +- .../list_replication_executions_responses.go | 2 +- .../list_replication_policies_responses.go | 2 +- .../list_replication_tasks_responses.go | 2 +- .../start_replication_parameters.go | 2 +- .../start_replication_responses.go | 2 +- .../replication/stop_replication_responses.go | 2 +- .../update_replication_policy_parameters.go | 2 +- .../update_replication_policy_responses.go | 2 +- .../repository/delete_repository_responses.go | 2 +- .../repository/get_repository_responses.go | 2 +- .../list_all_repositories_responses.go | 2 +- .../repository/list_repositories_responses.go | 2 +- .../update_repository_parameters.go | 2 +- .../repository/update_repository_responses.go | 2 +- .../retention/create_retention_parameters.go | 2 +- .../retention/create_retention_responses.go | 2 +- .../retention/delete_retention_responses.go | 2 +- .../get_rentenition_metadata_responses.go | 2 +- .../retention/get_retention_responses.go | 2 +- .../get_retention_task_log_responses.go | 2 +- .../list_retention_executions_responses.go | 2 +- .../list_retention_tasks_responses.go | 2 +- .../operate_retention_execution_responses.go | 2 +- .../trigger_retention_execution_responses.go | 2 +- .../retention/update_retention_parameters.go | 2 +- .../retention/update_retention_responses.go | 2 +- .../client/robot/create_robot_parameters.go | 2 +- .../client/robot/create_robot_responses.go | 2 +- .../client/robot/delete_robot_responses.go | 2 +- .../client/robot/get_robot_by_id_responses.go | 2 +- .../v2.0/client/robot/list_robot_responses.go | 2 +- .../client/robot/refresh_sec_parameters.go | 2 +- .../client/robot/refresh_sec_responses.go | 2 +- .../client/robot/update_robot_parameters.go | 2 +- .../client/robot/update_robot_responses.go | 2 +- .../robotv1/create_robot_v1_parameters.go | 2 +- .../robotv1/create_robot_v1_responses.go | 2 +- .../robotv1/delete_robot_v1_responses.go | 2 +- .../robotv1/get_robot_by_id_v1_responses.go | 2 +- .../client/robotv1/list_robot_v1_responses.go | 2 +- .../robotv1/update_robot_v1_parameters.go | 2 +- .../robotv1/update_robot_v1_responses.go | 2 +- .../client/scan/get_report_log_responses.go | 2 +- .../client/scan/scan_artifact_responses.go | 2 +- .../scan/stop_scan_artifact_responses.go | 2 +- .../create_scan_all_schedule_parameters.go | 2 +- .../create_scan_all_schedule_responses.go | 2 +- .../get_latest_scan_all_metrics_responses.go | 2 +- ...st_scheduled_scan_all_metrics_responses.go | 2 +- .../get_scan_all_schedule_responses.go | 2 +- .../scan_all/stop_scan_all_responses.go | 2 +- .../update_scan_all_schedule_parameters.go | 2 +- .../update_scan_all_schedule_responses.go | 2 +- .../download_scan_data_responses.go | 2 +- .../export_scan_data_parameters.go | 2 +- .../export_scan_data_responses.go | 2 +- ...an_data_export_execution_list_responses.go | 2 +- ...et_scan_data_export_execution_responses.go | 2 +- .../scanner/create_scanner_parameters.go | 2 +- .../scanner/create_scanner_responses.go | 2 +- .../scanner/delete_scanner_responses.go | 2 +- .../scanner/get_scanner_metadata_responses.go | 2 +- .../client/scanner/get_scanner_responses.go | 2 +- .../client/scanner/list_scanners_responses.go | 2 +- .../client/scanner/ping_scanner_parameters.go | 2 +- .../client/scanner/ping_scanner_responses.go | 2 +- .../set_scanner_as_default_parameters.go | 2 +- .../set_scanner_as_default_responses.go | 2 +- .../scanner/update_scanner_parameters.go | 2 +- .../scanner/update_scanner_responses.go | 2 +- .../schedule/get_schedule_paused_responses.go | 2 +- .../schedule/list_schedules_responses.go | 2 +- .../v2.0/client/search/search_responses.go | 2 +- .../get_security_summary_responses.go | 2 +- .../list_vulnerabilities_responses.go | 2 +- .../statistic/get_statistic_responses.go | 2 +- .../get_system_cve_allowlist_responses.go | 2 +- .../put_system_cve_allowlist_parameters.go | 2 +- .../put_system_cve_allowlist_responses.go | 2 +- .../client/systeminfo/get_cert_responses.go | 2 +- .../systeminfo/get_system_info_responses.go | 2 +- .../systeminfo/get_volumes_responses.go | 2 +- .../client/user/create_user_parameters.go | 2 +- .../v2.0/client/user/create_user_responses.go | 2 +- .../v2.0/client/user/delete_user_responses.go | 2 +- .../user/get_current_user_info_responses.go | 2 +- .../get_current_user_permissions_responses.go | 2 +- .../v2.0/client/user/get_user_responses.go | 2 +- .../v2.0/client/user/list_users_responses.go | 2 +- .../client/user/search_users_responses.go | 2 +- .../client/user/set_cli_secret_parameters.go | 2 +- .../client/user/set_cli_secret_responses.go | 2 +- .../user/set_user_sys_admin_parameters.go | 2 +- .../user/set_user_sys_admin_responses.go | 2 +- .../user/update_user_password_parameters.go | 2 +- .../user/update_user_password_responses.go | 2 +- .../user/update_user_profile_parameters.go | 2 +- .../user/update_user_profile_responses.go | 2 +- .../usergroup/create_user_group_parameters.go | 2 +- .../usergroup/create_user_group_responses.go | 2 +- .../usergroup/delete_user_group_responses.go | 2 +- .../usergroup/get_user_group_responses.go | 2 +- .../usergroup/list_user_groups_responses.go | 2 +- .../usergroup/search_user_groups_responses.go | 2 +- .../usergroup/update_user_group_parameters.go | 2 +- .../usergroup/update_user_group_responses.go | 2 +- ...te_webhook_policy_of_project_parameters.go | 2 +- ...ate_webhook_policy_of_project_responses.go | 2 +- ...ete_webhook_policy_of_project_responses.go | 2 +- .../get_logs_of_webhook_task_responses.go | 2 +- .../get_supported_event_types_responses.go | 2 +- ...get_webhook_policy_of_project_responses.go | 2 +- .../client/webhook/last_trigger_responses.go | 2 +- ..._executions_of_webhook_policy_responses.go | 2 +- ...st_tasks_of_webhook_execution_responses.go | 2 +- ...t_webhook_policies_of_project_responses.go | 2 +- ...te_webhook_policy_of_project_parameters.go | 2 +- ...ate_webhook_policy_of_project_responses.go | 2 +- .../webhookjob/list_webhook_jobs_responses.go | 2 +- pkg/imp/kubevirt/kubevirt/clientset.go | 4 +- .../kubevirt/fake/clientset_generated.go | 10 +-- .../kubevirt/typed/core/v1/core_client.go | 2 +- .../typed/core/v1/fake/fake_core_client.go | 2 +- .../kubevirt/typed/core/v1/kubevirt.go | 2 +- .../kubevirt/typed/core/v1/virtualmachine.go | 2 +- .../typed/core/v1/virtualmachineinstance.go | 2 +- .../v1/virtualmachineinstancemigration.go | 2 +- .../core/v1/virtualmachineinstancepreset.go | 2 +- .../v1/virtualmachineinstancereplicaset.go | 2 +- .../v1alpha1/fake/fake_snapshot_client.go | 2 +- .../snapshot/v1alpha1/snapshot_client.go | 2 +- .../v1alpha1/virtualmachinerestore.go | 2 +- .../v1alpha1/virtualmachinesnapshot.go | 2 +- .../v1alpha1/virtualmachinesnapshotcontent.go | 2 +- pkg/intializer/system_services.go | 8 +- pkg/intializer/test.go | 24 +++--- pkg/intializer/vm_port.go | 8 +- pkg/jobs/job_definition.go | 8 +- pkg/jobs/runner.go | 8 +- pkg/jobs/utils/utils.go | 12 +-- pkg/jobs/v2/deployment_jobs.go | 20 ++--- pkg/jobs/v2/sm_jobs.go | 16 ++-- pkg/jobs/v2/vm_jobs.go | 22 +++--- pkg/log/log.go | 2 +- pkg/metrics/setup.go | 4 +- pkg/services/cleaner/service.go | 6 +- .../cleaner/stale_resource_cleaner.go | 18 ++--- pkg/services/common.go | 4 +- pkg/services/confirm/common.go | 6 +- pkg/services/confirm/deployment_confirmer.go | 8 +- pkg/services/confirm/domain_confirmer.go | 10 +-- pkg/services/confirm/service.go | 6 +- pkg/services/confirm/sm_confirmer.go | 8 +- pkg/services/confirm/subsystems.go | 2 +- pkg/services/confirm/vm_confirmer.go | 8 +- pkg/services/job_execute/job_fetcher.go | 4 +- pkg/services/job_execute/service.go | 6 +- .../job_schedule/deployment_job_scheduler.go | 10 +-- pkg/services/job_schedule/service.go | 6 +- pkg/services/job_schedule/sm_job_scheduler.go | 10 +-- pkg/services/job_schedule/vm_job_scheduler.go | 10 +-- pkg/services/logger/pod_logger.go | 22 +++--- pkg/services/logger/pod_logger_control.go | 16 ++-- pkg/services/logger/service.go | 6 +- pkg/services/metrics_update/metric_updater.go | 12 +-- pkg/services/metrics_update/service.go | 6 +- pkg/services/status_update/common.go | 6 +- .../deployment_status_fetcher.go | 10 +-- .../deployment_status_listener.go | 16 ++-- pkg/services/status_update/service.go | 6 +- .../status_update/vm_status_fetcher.go | 8 +- .../status_update/vm_status_listener.go | 16 ++-- pkg/services/synchronize/fetch_gpu.go | 18 ++--- pkg/services/synchronize/service.go | 6 +- pkg/services/synchronize/update_gpu_leases.go | 10 +-- .../system_state_poll/capacities_worker.go | 14 ++-- pkg/services/system_state_poll/common.go | 4 +- .../system_state_poll/gpu_info_worker.go | 14 ++-- pkg/services/system_state_poll/service.go | 6 +- .../system_state_poll/stats_worker.go | 12 +-- .../system_state_poll/status_worker.go | 14 ++-- pkg/services/workers.go | 8 +- pkg/subsystems/harbor/client.go | 2 +- pkg/subsystems/harbor/common.go | 12 +-- .../harbor/models/project_create.go | 2 +- .../harbor/models/project_public.go | 2 +- .../harbor/models/repository_public.go | 2 +- pkg/subsystems/harbor/models/robot_public.go | 2 +- .../harbor/models/webhook_public.go | 2 +- pkg/subsystems/harbor/project.go | 6 +- pkg/subsystems/harbor/repository.go | 8 +- pkg/subsystems/harbor/robot.go | 10 +-- pkg/subsystems/harbor/webhook.go | 10 +-- pkg/subsystems/host_api/capacities.go | 2 +- pkg/subsystems/host_api/gpu_info.go | 2 +- pkg/subsystems/host_api/node_info.go | 2 +- pkg/subsystems/host_api/status.go | 2 +- pkg/subsystems/k8s/client.go | 2 +- pkg/subsystems/k8s/deployment.go | 4 +- pkg/subsystems/k8s/hpa.go | 4 +- pkg/subsystems/k8s/ingress.go | 6 +- pkg/subsystems/k8s/job.go | 4 +- pkg/subsystems/k8s/kubevirt.go | 2 +- pkg/subsystems/k8s/logs.go | 8 +- pkg/subsystems/k8s/manifests.go | 6 +- pkg/subsystems/k8s/models/common.go | 2 +- pkg/subsystems/k8s/models/ingress_public.go | 2 +- pkg/subsystems/k8s/models/vm.go | 2 +- pkg/subsystems/k8s/models/vm_snapshot.go | 2 +- pkg/subsystems/k8s/models/vm_status.go | 2 +- pkg/subsystems/k8s/namespace.go | 4 +- pkg/subsystems/k8s/network_policy.go | 4 +- pkg/subsystems/k8s/node.go | 2 +- pkg/subsystems/k8s/pod.go | 4 +- pkg/subsystems/k8s/pv.go | 4 +- pkg/subsystems/k8s/pvc.go | 4 +- pkg/subsystems/k8s/secret.go | 4 +- pkg/subsystems/k8s/service.go | 4 +- pkg/subsystems/k8s/status.go | 8 +- pkg/subsystems/k8s/vm.go | 8 +- pkg/subsystems/k8s/vm_snapshot.go | 4 +- pkg/subsystems/rancher/cluster.go | 2 +- pkg/sys/auth.go | 4 +- pkg/sys/client_context.go | 8 +- routers/api/v2/api_key.go | 10 +-- routers/api/v2/deployment.go | 26 +++---- routers/api/v2/deployment_ci_config.go | 8 +- routers/api/v2/deployment_command.go | 10 +-- routers/api/v2/deployment_hook.go | 12 +-- routers/api/v2/deployment_logs.go | 12 +-- routers/api/v2/discover.go | 4 +- routers/api/v2/gpu_group.go | 14 ++-- routers/api/v2/gpu_lease.go | 20 ++--- routers/api/v2/hosts.go | 6 +- routers/api/v2/job.go | 20 ++--- .../api/v2/middleware/access_gpu_routes.go | 6 +- .../v2/middleware/create_storage_manager.go | 14 ++-- routers/api/v2/middleware/synchronize_user.go | 10 +-- routers/api/v2/notification.go | 16 ++-- routers/api/v2/register.go | 8 +- routers/api/v2/resource_migration.go | 14 ++-- routers/api/v2/sm.go | 22 +++--- routers/api/v2/snapshot.go | 20 ++--- routers/api/v2/system.go | 6 +- routers/api/v2/team.go | 24 +++--- routers/api/v2/user.go | 20 ++--- routers/api/v2/utils.go | 6 +- routers/api/v2/vm.go | 26 +++---- routers/api/v2/vm_action.go | 14 ++-- routers/api/v2/worker_status.go | 10 +-- routers/api/v2/zone.go | 8 +- routers/api/validators/validators.go | 4 +- routers/router.go | 20 ++--- routers/routes/deployment.go | 4 +- routers/routes/discover.go | 2 +- routers/routes/gpu_group.go | 2 +- routers/routes/gpu_lease.go | 2 +- routers/routes/host.go | 2 +- routers/routes/job.go | 2 +- routers/routes/metrics.go | 4 +- routers/routes/notification.go | 2 +- routers/routes/register.go | 2 +- routers/routes/resource_migration.go | 2 +- routers/routes/sm.go | 2 +- routers/routes/snapshot.go | 2 +- routers/routes/system.go | 2 +- routers/routes/team.go | 2 +- routers/routes/user.go | 2 +- routers/routes/vm.go | 2 +- routers/routes/vm_action.go | 2 +- routers/routes/zone.go | 2 +- service/client.go | 6 +- service/clients/v2.go | 4 +- service/core/auth_info.go | 4 +- service/core/cache.go | 2 +- service/generators/harbor_generator.go | 2 +- service/generators/k8s_generator.go | 2 +- service/resources/resource_creator.go | 4 +- service/resources/resource_deleter.go | 2 +- .../resources/resource_placeholder_creator.go | 2 +- service/resources/resource_repairer.go | 6 +- service/resources/resource_updater.go | 4 +- service/utils/utils.go | 4 +- service/v2/api/api_client.go | 32 ++++---- service/v2/client.go | 26 +++---- service/v2/deployments/api_client.go | 10 +-- service/v2/deployments/ci_config_service.go | 12 +-- service/v2/deployments/client/client.go | 6 +- service/v2/deployments/deployment_service.go | 30 +++---- .../v2/deployments/harbor_service/client.go | 22 +++--- .../harbor_service/harbor_service.go | 16 ++-- service/v2/deployments/hook_service.go | 2 +- service/v2/deployments/k8s_service/client.go | 20 ++--- .../v2/deployments/k8s_service/k8s_service.go | 24 +++--- service/v2/deployments/logs_service.go | 10 +-- service/v2/deployments/opts/opts.go | 6 +- .../deployments/resources/harbor_generator.go | 12 +-- .../v2/deployments/resources/k8s_generator.go | 24 +++--- service/v2/discovery/api_client.go | 4 +- service/v2/discovery/discover_service.go | 6 +- service/v2/events/api_client.go | 4 +- service/v2/events/event_service.go | 4 +- service/v2/jobs/api_client.go | 8 +- service/v2/jobs/job_service.go | 12 +-- service/v2/jobs/opts/opts.go | 2 +- service/v2/notifications/api_client.go | 8 +- .../v2/notifications/notification_service.go | 12 +-- service/v2/notifications/opts/opts.go | 2 +- service/v2/resource_migrations/api_client.go | 4 +- service/v2/resource_migrations/opts/opts.go | 2 +- .../resource_migration_service.go | 22 +++--- service/v2/sms/api_client.go | 8 +- service/v2/sms/client/client.go | 6 +- service/v2/sms/k8s_service/client.go | 20 ++--- service/v2/sms/k8s_service/k8s_service.go | 16 ++-- service/v2/sms/opts/opts.go | 4 +- service/v2/sms/resources/k8s_generator.go | 22 +++--- service/v2/sms/sm_service.go | 18 ++--- service/v2/system/api_client.go | 4 +- service/v2/system/host_service.go | 4 +- service/v2/system/registration_service.go | 10 +-- service/v2/system/system_service.go | 8 +- service/v2/system/worker_service.go | 6 +- service/v2/system/zone_service.go | 8 +- service/v2/teams/api_client.go | 10 +-- service/v2/teams/opts/opts.go | 2 +- service/v2/teams/team_service.go | 20 ++--- service/v2/users/api_client.go | 14 ++-- service/v2/users/api_key/api_key.go | 10 +-- service/v2/users/api_key/client.go | 4 +- service/v2/users/opts/opts.go | 2 +- service/v2/users/user_service.go | 14 ++-- service/v2/utils/utils.go | 2 +- service/v2/vms/api_client.go | 16 ++-- service/v2/vms/client/client.go | 8 +- service/v2/vms/gpu_groups/client.go | 6 +- .../v2/vms/gpu_groups/gpu_groups_service.go | 8 +- service/v2/vms/gpu_leases/client.go | 6 +- .../v2/vms/gpu_leases/gpu_lease_service.go | 12 +-- service/v2/vms/k8s_service/client.go | 20 ++--- service/v2/vms/k8s_service/k8s_service.go | 28 +++---- .../v2/vms/k8s_service/snapshot_service.go | 8 +- service/v2/vms/opts/opts.go | 8 +- service/v2/vms/resources/k8s_generator.go | 20 ++--- service/v2/vms/snapshots/client.go | 6 +- service/v2/vms/snapshots/snapshot_service.go | 8 +- service/v2/vms/vm_service.go | 34 ++++---- test/acc/common.go | 6 +- test/acc/subsystems/harbor/helpers.go | 10 +-- test/acc/subsystems/harbor/main_test.go | 2 +- test/acc/subsystems/harbor/project_test.go | 2 +- test/acc/subsystems/harbor/robot_test.go | 6 +- test/acc/subsystems/harbor/webhook_test.go | 4 +- test/acc/subsystems/k8s/deployment_test.go | 6 +- test/acc/subsystems/k8s/helpers.go | 10 +-- test/acc/subsystems/k8s/hpa_test.go | 2 +- test/acc/subsystems/k8s/ingress_test.go | 4 +- test/acc/subsystems/k8s/main_test.go | 2 +- .../acc/subsystems/k8s/network_policy_test.go | 2 +- test/acc/subsystems/k8s/secret_test.go | 4 +- test/acc/subsystems/k8s/service_test.go | 2 +- test/acc/subsystems/k8s/vm_test.go | 4 +- test/e2e/common.go | 6 +- test/e2e/setup.go | 2 +- test/e2e/v2/deployment_utils.go | 10 +-- test/e2e/v2/deployments/routes_test.go | 8 +- test/e2e/v2/gpu_groups/routes_test.go | 4 +- test/e2e/v2/gpu_groups_utils.go | 4 +- test/e2e/v2/gpu_leases/routes_test.go | 8 +- test/e2e/v2/gpu_leases_utils.go | 4 +- test/e2e/v2/job_utils.go | 6 +- test/e2e/v2/jobs/routes_test.go | 8 +- test/e2e/v2/notifications/route_test.go | 8 +- test/e2e/v2/notifications_utils.go | 4 +- test/e2e/v2/resource_migrations/route_test.go | 8 +- test/e2e/v2/resource_migrations_utils.go | 6 +- test/e2e/v2/sm_utils.go | 4 +- test/e2e/v2/sms/route_test.go | 8 +- test/e2e/v2/team_utils.go | 8 +- test/e2e/v2/teams/routes_test.go | 8 +- test/e2e/v2/user_utils.go | 6 +- test/e2e/v2/users/routes_test.go | 8 +- test/e2e/v2/vm_utils.go | 6 +- test/e2e/v2/vms/routes_test.go | 8 +- test/e2e/v2/zone_utils.go | 4 +- test/e2e/v2/zones/routes_test.go | 4 +- utils/requestutils/utils.go | 2 +- utils/subsystemutils/utils.go | 2 +- utils/utils.go | 2 +- 605 files changed, 1540 insertions(+), 1540 deletions(-) diff --git a/cmd/flag.go b/cmd/flag.go index 60021a03..e41cdbd8 100644 --- a/cmd/flag.go +++ b/cmd/flag.go @@ -2,15 +2,15 @@ package cmd import ( "context" - "go-deploy/pkg/services/cleaner" - "go-deploy/pkg/services/confirm" - "go-deploy/pkg/services/job_execute" - "go-deploy/pkg/services/job_schedule" - "go-deploy/pkg/services/logger" - metricsWorker "go-deploy/pkg/services/metrics_update" - "go-deploy/pkg/services/status_update" - "go-deploy/pkg/services/synchronize" - "go-deploy/pkg/services/system_state_poll" + "github.com/kthcloud/go-deploy/pkg/services/cleaner" + "github.com/kthcloud/go-deploy/pkg/services/confirm" + "github.com/kthcloud/go-deploy/pkg/services/job_execute" + "github.com/kthcloud/go-deploy/pkg/services/job_schedule" + "github.com/kthcloud/go-deploy/pkg/services/logger" + metricsWorker "github.com/kthcloud/go-deploy/pkg/services/metrics_update" + "github.com/kthcloud/go-deploy/pkg/services/status_update" + "github.com/kthcloud/go-deploy/pkg/services/synchronize" + "github.com/kthcloud/go-deploy/pkg/services/system_state_poll" ) // FlagDefinition represents a definition for a flag that is passed to the program's executable. diff --git a/cmd/server.go b/cmd/server.go index e7cee8c2..93cc4bd0 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -6,15 +6,15 @@ import ( argFlag "flag" "fmt" "github.com/gin-gonic/gin" - "go-deploy/models/mode" - "go-deploy/pkg/config" - "go-deploy/pkg/db" - "go-deploy/pkg/db/migrate" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/intializer" - "go-deploy/pkg/log" - "go-deploy/pkg/metrics" - "go-deploy/routers" + "github.com/kthcloud/go-deploy/models/mode" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/migrate" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/intializer" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/metrics" + "github.com/kthcloud/go-deploy/routers" "net/http" "os" "time" diff --git a/go.mod b/go.mod index a94145b4..d7bf6c1a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module go-deploy +module github.com/kthcloud/go-deploy go 1.22.0 diff --git a/main.go b/main.go index 9251e962..9e7e9120 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ package main import ( - "go-deploy/cmd" + "github.com/kthcloud/go-deploy/cmd" "os" ) diff --git a/models/config/config.go b/models/config/config.go index 247cfc9c..41f45c87 100644 --- a/models/config/config.go +++ b/models/config/config.go @@ -1,8 +1,8 @@ package config import ( - "go-deploy/models/model" - "go-deploy/pkg/imp/kubevirt/kubevirt" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt" "k8s.io/client-go/kubernetes" "time" ) diff --git a/models/config/config_convert.go b/models/config/config_convert.go index 72e8043c..ced69d42 100644 --- a/models/config/config_convert.go +++ b/models/config/config_convert.go @@ -1,7 +1,7 @@ package config import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" ) // ToDTO converts a Zone to a body.ZoneRead DTO. diff --git a/models/config/helpers.go b/models/config/helpers.go index 73c0cc25..0faeb700 100644 --- a/models/config/helpers.go +++ b/models/config/helpers.go @@ -1,7 +1,7 @@ package config import ( - "go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/model" "gopkg.in/yaml.v3" "os" "sync" diff --git a/models/model/api_key.go b/models/model/api_key.go index 6426591d..0a531cb2 100644 --- a/models/model/api_key.go +++ b/models/model/api_key.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" "time" ) diff --git a/models/model/deployment_convert.go b/models/model/deployment_convert.go index 99d3f70e..58c2610a 100644 --- a/models/model/deployment_convert.go +++ b/models/model/deployment_convert.go @@ -2,9 +2,9 @@ package model import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/pkg/log" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/utils" "golang.org/x/net/idna" "strconv" ) diff --git a/models/model/deployment_subsystems.go b/models/model/deployment_subsystems.go index dba11919..630ac212 100644 --- a/models/model/deployment_subsystems.go +++ b/models/model/deployment_subsystems.go @@ -1,8 +1,8 @@ package model import ( - harborModels "go-deploy/pkg/subsystems/harbor/models" - k8sModels "go-deploy/pkg/subsystems/k8s/models" + harborModels "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" + k8sModels "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" ) type DeploymentSubsystems struct { diff --git a/models/model/discover.go b/models/model/discover.go index 0a961e66..0e7a415a 100644 --- a/models/model/discover.go +++ b/models/model/discover.go @@ -1,7 +1,7 @@ package model import ( - body2 "go-deploy/dto/v2/body" + body2 "github.com/kthcloud/go-deploy/dto/v2/body" ) type Discover struct { diff --git a/models/model/gpu_group.go b/models/model/gpu_group.go index 851dce35..d7d603d7 100644 --- a/models/model/gpu_group.go +++ b/models/model/gpu_group.go @@ -2,8 +2,8 @@ package model import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/utils" ) // GpuGroup represents a group of GPUs for VM v2 diff --git a/models/model/gpu_lease.go b/models/model/gpu_lease.go index 4f9ada98..6cee1a46 100644 --- a/models/model/gpu_lease.go +++ b/models/model/gpu_lease.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" "time" ) diff --git a/models/model/gpu_lease_convert.go b/models/model/gpu_lease_convert.go index 45773202..c5106488 100644 --- a/models/model/gpu_lease_convert.go +++ b/models/model/gpu_lease_convert.go @@ -1,8 +1,8 @@ package model import ( - "go-deploy/dto/v2/body" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/utils" "time" ) diff --git a/models/model/host.go b/models/model/host.go index 850711a6..77d8fb8e 100644 --- a/models/model/host.go +++ b/models/model/host.go @@ -2,7 +2,7 @@ package model import ( "fmt" - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" "time" ) diff --git a/models/model/job_convert.go b/models/model/job_convert.go index d65c8b34..826b3dce 100644 --- a/models/model/job_convert.go +++ b/models/model/job_convert.go @@ -1,8 +1,8 @@ package model import ( - "go-deploy/dto/v2/body" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/utils" ) // ToDTO converts a Job to a body.JobRead DTO. diff --git a/models/model/notification.go b/models/model/notification.go index 00890b87..c4d57d3a 100644 --- a/models/model/notification.go +++ b/models/model/notification.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" "time" ) diff --git a/models/model/quotas.go b/models/model/quotas.go index 302b8c2f..7bd8d345 100644 --- a/models/model/quotas.go +++ b/models/model/quotas.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" ) type Quotas struct { diff --git a/models/model/resource_migration.go b/models/model/resource_migration.go index b964d0ae..c95d0e0f 100644 --- a/models/model/resource_migration.go +++ b/models/model/resource_migration.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" "time" ) diff --git a/models/model/resource_migration_params.go b/models/model/resource_migration_params.go index 1ffc08d4..46674e0e 100644 --- a/models/model/resource_migration_params.go +++ b/models/model/resource_migration_params.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" ) type ResourceMigrationCreateParams struct { diff --git a/models/model/role.go b/models/model/role.go index aba0ebf1..944ee9e3 100644 --- a/models/model/role.go +++ b/models/model/role.go @@ -2,7 +2,7 @@ package model import ( "github.com/fatih/structs" - body2 "go-deploy/dto/v2/body" + body2 "github.com/kthcloud/go-deploy/dto/v2/body" "sort" ) diff --git a/models/model/sm_dto.go b/models/model/sm_dto.go index ff136464..7f2e0b74 100644 --- a/models/model/sm_dto.go +++ b/models/model/sm_dto.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" ) // ToDTO converts an SM to a body.SmRead DTO. diff --git a/models/model/sm_subsystems.go b/models/model/sm_subsystems.go index 1f7b6ee3..a25b9aee 100644 --- a/models/model/sm_subsystems.go +++ b/models/model/sm_subsystems.go @@ -1,7 +1,7 @@ package model import ( - k8sModels "go-deploy/pkg/subsystems/k8s/models" + k8sModels "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" ) type SmSubsystems struct { diff --git a/models/model/team_convert.go b/models/model/team_convert.go index e92f1baf..7627c673 100644 --- a/models/model/team_convert.go +++ b/models/model/team_convert.go @@ -1,8 +1,8 @@ package model import ( - "go-deploy/dto/v2/body" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/utils" "sort" "time" ) diff --git a/models/model/user_convert.go b/models/model/user_convert.go index db8a0fbf..0cd5ae4f 100644 --- a/models/model/user_convert.go +++ b/models/model/user_convert.go @@ -1,8 +1,8 @@ package model import ( - "go-deploy/dto/v2/body" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/log" "math" ) diff --git a/models/model/vm_convert.go b/models/model/vm_convert.go index 4b56afa4..d12a161c 100644 --- a/models/model/vm_convert.go +++ b/models/model/vm_convert.go @@ -2,9 +2,9 @@ package model import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/pkg/subsystems" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/utils" "time" ) diff --git a/models/model/vm_subsystems.go b/models/model/vm_subsystems.go index f1e83153..dc9d9685 100644 --- a/models/model/vm_subsystems.go +++ b/models/model/vm_subsystems.go @@ -1,7 +1,7 @@ package model import ( - k8sModels "go-deploy/pkg/subsystems/k8s/models" + k8sModels "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" ) type VmK8s struct { diff --git a/models/model/worker_status.go b/models/model/worker_status.go index c0a713bb..e92a359a 100644 --- a/models/model/worker_status.go +++ b/models/model/worker_status.go @@ -1,7 +1,7 @@ package model import ( - "go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/body" "time" ) diff --git a/pkg/auth/gin_keycloak.go b/pkg/auth/gin_keycloak.go index 33c43f2f..7a89d0a1 100644 --- a/pkg/auth/gin_keycloak.go +++ b/pkg/auth/gin_keycloak.go @@ -7,8 +7,8 @@ import ( "encoding/base64" "encoding/json" "errors" - "go-deploy/models/mode" - "go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/models/mode" + "github.com/kthcloud/go-deploy/pkg/config" "io/ioutil" "math/big" "net/http" diff --git a/pkg/config/config.go b/pkg/config/config.go index 69b809c5..3b03a3f2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -3,12 +3,12 @@ package config import ( "fmt" "github.com/mitchellh/mapstructure" - "go-deploy/models/config" - "go-deploy/models/mode" - "go-deploy/models/version" - "go-deploy/pkg/imp/kubevirt/kubevirt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/rancher" + "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/mode" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/rancher" "gopkg.in/yaml.v3" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" diff --git a/pkg/db/base.go b/pkg/db/base.go index 292a78a0..9493c4aa 100644 --- a/pkg/db/base.go +++ b/pkg/db/base.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/pkg/db/db.go b/pkg/db/db.go index f24082b7..8d77e558 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -2,7 +2,7 @@ package db import ( "github.com/redis/go-redis/v9" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/log" "go.mongodb.org/mongo-driver/mongo" ) diff --git a/pkg/db/key_value/client.go b/pkg/db/key_value/client.go index 712d6a8b..33b95e85 100644 --- a/pkg/db/key_value/client.go +++ b/pkg/db/key_value/client.go @@ -5,8 +5,8 @@ import ( "errors" "fmt" "github.com/redis/go-redis/v9" - "go-deploy/pkg/db" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/utils" "regexp" "time" ) diff --git a/pkg/db/message_queue/client.go b/pkg/db/message_queue/client.go index 7149ad04..504296b7 100644 --- a/pkg/db/message_queue/client.go +++ b/pkg/db/message_queue/client.go @@ -5,8 +5,8 @@ import ( "encoding/json" "fmt" "github.com/redis/go-redis/v9" - "go-deploy/pkg/db" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/log" ) var ( diff --git a/pkg/db/migrate/migrate.go b/pkg/db/migrate/migrate.go index 071a3a2a..99174bfd 100644 --- a/pkg/db/migrate/migrate.go +++ b/pkg/db/migrate/migrate.go @@ -2,9 +2,9 @@ package migrator import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/log" "go.mongodb.org/mongo-driver/bson" ) diff --git a/pkg/db/mongo.go b/pkg/db/mongo.go index 6a7428c0..6606b135 100644 --- a/pkg/db/mongo.go +++ b/pkg/db/mongo.go @@ -3,8 +3,8 @@ package db import ( "context" "fmt" - "go-deploy/pkg/config" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/pkg/db/redis.go b/pkg/db/redis.go index 9aa007aa..2277babe 100644 --- a/pkg/db/redis.go +++ b/pkg/db/redis.go @@ -4,8 +4,8 @@ import ( "context" "fmt" "github.com/redis/go-redis/v9" - "go-deploy/pkg/config" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" ) // setupRedis initializes the Redis connection. diff --git a/pkg/db/resources/base_clients/activity_resource_client.go b/pkg/db/resources/base_clients/activity_resource_client.go index 132b7e30..81184014 100644 --- a/pkg/db/resources/base_clients/activity_resource_client.go +++ b/pkg/db/resources/base_clients/activity_resource_client.go @@ -3,8 +3,8 @@ package base_clients import ( "context" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "time" diff --git a/pkg/db/resources/base_clients/resource_client.go b/pkg/db/resources/base_clients/resource_client.go index b224479a..bf215663 100644 --- a/pkg/db/resources/base_clients/resource_client.go +++ b/pkg/db/resources/base_clients/resource_client.go @@ -2,7 +2,7 @@ package base_clients import ( "fmt" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "time" diff --git a/pkg/db/resources/base_clients/timestamped_resource_client.go b/pkg/db/resources/base_clients/timestamped_resource_client.go index 6dc9195d..103c00a8 100644 --- a/pkg/db/resources/base_clients/timestamped_resource_client.go +++ b/pkg/db/resources/base_clients/timestamped_resource_client.go @@ -3,7 +3,7 @@ package base_clients import ( "context" "errors" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/pkg/db/resources/deployment_repo/client.go b/pkg/db/resources/deployment_repo/client.go index 9fb160e5..8dfe4b7e 100644 --- a/pkg/db/resources/deployment_repo/client.go +++ b/pkg/db/resources/deployment_repo/client.go @@ -1,9 +1,9 @@ package deployment_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "time" diff --git a/pkg/db/resources/deployment_repo/db.go b/pkg/db/resources/deployment_repo/db.go index 8595e3e9..f7da4a33 100644 --- a/pkg/db/resources/deployment_repo/db.go +++ b/pkg/db/resources/deployment_repo/db.go @@ -5,12 +5,12 @@ import ( "errors" "fmt" "github.com/google/uuid" - "go-deploy/models/model" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/db" - "go-deploy/pkg/log" - rErrors "go-deploy/service/errors" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/log" + rErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/pkg/db/resources/event_repo/client.go b/pkg/db/resources/event_repo/client.go index 1700108f..0cd9279e 100644 --- a/pkg/db/resources/event_repo/client.go +++ b/pkg/db/resources/event_repo/client.go @@ -1,9 +1,9 @@ package event_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" ) diff --git a/pkg/db/resources/event_repo/db.go b/pkg/db/resources/event_repo/db.go index e4542f6f..ed58502c 100644 --- a/pkg/db/resources/event_repo/db.go +++ b/pkg/db/resources/event_repo/db.go @@ -2,7 +2,7 @@ package event_repo import ( "context" - "go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/model" "time" ) diff --git a/pkg/db/resources/gpu_group_repo/client.go b/pkg/db/resources/gpu_group_repo/client.go index 2ab6f86a..9093ab50 100644 --- a/pkg/db/resources/gpu_group_repo/client.go +++ b/pkg/db/resources/gpu_group_repo/client.go @@ -1,9 +1,9 @@ package gpu_group_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" ) diff --git a/pkg/db/resources/gpu_group_repo/db.go b/pkg/db/resources/gpu_group_repo/db.go index a601290c..6387399c 100644 --- a/pkg/db/resources/gpu_group_repo/db.go +++ b/pkg/db/resources/gpu_group_repo/db.go @@ -3,9 +3,9 @@ package gpu_group_repo import ( "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" ) diff --git a/pkg/db/resources/gpu_lease_repo/client.go b/pkg/db/resources/gpu_lease_repo/client.go index 0a4baf65..d85a7035 100644 --- a/pkg/db/resources/gpu_lease_repo/client.go +++ b/pkg/db/resources/gpu_lease_repo/client.go @@ -1,9 +1,9 @@ package gpu_lease_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/gpu_lease_repo/db.go b/pkg/db/resources/gpu_lease_repo/db.go index 4dd458c8..7a0336e2 100644 --- a/pkg/db/resources/gpu_lease_repo/db.go +++ b/pkg/db/resources/gpu_lease_repo/db.go @@ -2,8 +2,8 @@ package gpu_lease_repo import ( "errors" - "go-deploy/models/model" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/host_repo/client.go b/pkg/db/resources/host_repo/client.go index fbc3c30e..406e4317 100644 --- a/pkg/db/resources/host_repo/client.go +++ b/pkg/db/resources/host_repo/client.go @@ -1,9 +1,9 @@ package host_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/host_repo/db.go b/pkg/db/resources/host_repo/db.go index 62dc3f54..f592498e 100644 --- a/pkg/db/resources/host_repo/db.go +++ b/pkg/db/resources/host_repo/db.go @@ -3,7 +3,7 @@ package host_repo import ( "context" "fmt" - "go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/model" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/job_repo/client.go b/pkg/db/resources/job_repo/client.go index ac723a42..1ad6adaf 100644 --- a/pkg/db/resources/job_repo/client.go +++ b/pkg/db/resources/job_repo/client.go @@ -1,9 +1,9 @@ package job_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/job_repo/db.go b/pkg/db/resources/job_repo/db.go index ef062c68..1c04052c 100644 --- a/pkg/db/resources/job_repo/db.go +++ b/pkg/db/resources/job_repo/db.go @@ -4,8 +4,8 @@ import ( "context" "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/pkg/db/resources/notification_repo/client.go b/pkg/db/resources/notification_repo/client.go index f3364ad9..a2377c99 100644 --- a/pkg/db/resources/notification_repo/client.go +++ b/pkg/db/resources/notification_repo/client.go @@ -1,9 +1,9 @@ package notification_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" ) diff --git a/pkg/db/resources/notification_repo/db.go b/pkg/db/resources/notification_repo/db.go index 6705a77f..0a4ab06f 100644 --- a/pkg/db/resources/notification_repo/db.go +++ b/pkg/db/resources/notification_repo/db.go @@ -3,7 +3,7 @@ package notification_repo import ( "context" "fmt" - "go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/model" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/resource_migration_repo/client.go b/pkg/db/resources/resource_migration_repo/client.go index 15ca2a15..ccb95b6c 100644 --- a/pkg/db/resources/resource_migration_repo/client.go +++ b/pkg/db/resources/resource_migration_repo/client.go @@ -1,9 +1,9 @@ package resource_migration_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" ) diff --git a/pkg/db/resources/resource_migration_repo/db.go b/pkg/db/resources/resource_migration_repo/db.go index 0e8ff8ee..6d730a01 100644 --- a/pkg/db/resources/resource_migration_repo/db.go +++ b/pkg/db/resources/resource_migration_repo/db.go @@ -2,8 +2,8 @@ package resource_migration_repo import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/sm_repo/client.go b/pkg/db/resources/sm_repo/client.go index 8c72307d..fbb101a5 100644 --- a/pkg/db/resources/sm_repo/client.go +++ b/pkg/db/resources/sm_repo/client.go @@ -1,9 +1,9 @@ package sm_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" ) diff --git a/pkg/db/resources/sm_repo/db.go b/pkg/db/resources/sm_repo/db.go index 8a6047fb..04234b29 100644 --- a/pkg/db/resources/sm_repo/db.go +++ b/pkg/db/resources/sm_repo/db.go @@ -4,8 +4,8 @@ import ( "context" "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/system_capacities_repo/client.go b/pkg/db/resources/system_capacities_repo/client.go index 79c6ffe0..2190a443 100644 --- a/pkg/db/resources/system_capacities_repo/client.go +++ b/pkg/db/resources/system_capacities_repo/client.go @@ -1,9 +1,9 @@ package system_capacities_repo import ( - "go-deploy/dto/v2/body" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" ) // Client is the client for the system capacities model. diff --git a/pkg/db/resources/system_gpu_info_repo/client.go b/pkg/db/resources/system_gpu_info_repo/client.go index db974c55..71507cce 100644 --- a/pkg/db/resources/system_gpu_info_repo/client.go +++ b/pkg/db/resources/system_gpu_info_repo/client.go @@ -1,9 +1,9 @@ package system_gpu_info_repo import ( - "go-deploy/dto/v2/body" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" ) // Client is the client for the system GPU info model. diff --git a/pkg/db/resources/system_stats_repo/client.go b/pkg/db/resources/system_stats_repo/client.go index 11bc8438..4edc8678 100644 --- a/pkg/db/resources/system_stats_repo/client.go +++ b/pkg/db/resources/system_stats_repo/client.go @@ -1,9 +1,9 @@ package system_stats_repo import ( - "go-deploy/dto/v2/body" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" ) // Client is the client for the system stats model. diff --git a/pkg/db/resources/system_status_repo/client.go b/pkg/db/resources/system_status_repo/client.go index 99981a17..16802b9e 100644 --- a/pkg/db/resources/system_status_repo/client.go +++ b/pkg/db/resources/system_status_repo/client.go @@ -1,9 +1,9 @@ package system_status_repo import ( - "go-deploy/dto/v2/body" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" ) // Client is the client for the system status model. diff --git a/pkg/db/resources/team_repo/client.go b/pkg/db/resources/team_repo/client.go index 5301aba4..eab336c7 100644 --- a/pkg/db/resources/team_repo/client.go +++ b/pkg/db/resources/team_repo/client.go @@ -1,9 +1,9 @@ package team_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/team_repo/db.go b/pkg/db/resources/team_repo/db.go index f65b17c8..9ca48a8e 100644 --- a/pkg/db/resources/team_repo/db.go +++ b/pkg/db/resources/team_repo/db.go @@ -3,8 +3,8 @@ package team_repo import ( "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/user_repo/client.go b/pkg/db/resources/user_repo/client.go index 04465ef3..bd005d61 100644 --- a/pkg/db/resources/user_repo/client.go +++ b/pkg/db/resources/user_repo/client.go @@ -1,9 +1,9 @@ package user_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/user_repo/db.go b/pkg/db/resources/user_repo/db.go index c86e49dd..2828e00f 100644 --- a/pkg/db/resources/user_repo/db.go +++ b/pkg/db/resources/user_repo/db.go @@ -3,9 +3,9 @@ package user_repo import ( "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db" - rErrors "go-deploy/pkg/db/resources/errors" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + rErrors "github.com/kthcloud/go-deploy/pkg/db/resources/errors" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/db/resources/vm_port_repo/client.go b/pkg/db/resources/vm_port_repo/client.go index a6b713d7..52efea14 100644 --- a/pkg/db/resources/vm_port_repo/client.go +++ b/pkg/db/resources/vm_port_repo/client.go @@ -1,9 +1,9 @@ package vm_port_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" ) diff --git a/pkg/db/resources/vm_port_repo/db.go b/pkg/db/resources/vm_port_repo/db.go index 92c29fed..e843b310 100644 --- a/pkg/db/resources/vm_port_repo/db.go +++ b/pkg/db/resources/vm_port_repo/db.go @@ -3,7 +3,7 @@ package vm_port_repo import ( "context" "errors" - "go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/model" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/pkg/db/resources/vm_repo/client.go b/pkg/db/resources/vm_repo/client.go index f7c0498d..625c2ec8 100644 --- a/pkg/db/resources/vm_repo/client.go +++ b/pkg/db/resources/vm_repo/client.go @@ -1,10 +1,10 @@ package vm_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" - "go-deploy/service/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/service/utils" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "time" diff --git a/pkg/db/resources/vm_repo/db.go b/pkg/db/resources/vm_repo/db.go index 38250de7..cce72fe3 100644 --- a/pkg/db/resources/vm_repo/db.go +++ b/pkg/db/resources/vm_repo/db.go @@ -5,12 +5,12 @@ import ( "errors" "fmt" "github.com/google/uuid" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/db" - rErrors "go-deploy/service/errors" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/db" + rErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "time" diff --git a/pkg/db/resources/worker_status_repo/client.go b/pkg/db/resources/worker_status_repo/client.go index dc23509c..c449b94c 100644 --- a/pkg/db/resources/worker_status_repo/client.go +++ b/pkg/db/resources/worker_status_repo/client.go @@ -1,9 +1,9 @@ package worker_status_repo import ( - "go-deploy/models/model" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/base_clients" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/mongo" ) diff --git a/pkg/imp/harbor/harbor/client.go b/pkg/imp/harbor/harbor/client.go index 4a356b76..d5a71a26 100644 --- a/pkg/imp/harbor/harbor/client.go +++ b/pkg/imp/harbor/harbor/client.go @@ -9,7 +9,7 @@ import ( "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" - v2client "go-deploy/pkg/imp/harbor/sdk/v2.0/client" + v2client "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client" ) // InsecureTransport provides a insecure RoundTripper and disable the HTTP2 try. diff --git a/pkg/imp/harbor/harbor/client_test.go b/pkg/imp/harbor/harbor/client_test.go index 384fd879..13adb350 100644 --- a/pkg/imp/harbor/harbor/client_test.go +++ b/pkg/imp/harbor/harbor/client_test.go @@ -8,10 +8,10 @@ import ( "github.com/go-openapi/runtime" "github.com/stretchr/testify/assert" - "go-deploy/pkg/imp/harbor/harbor" - "go-deploy/pkg/imp/harbor/harbor/test" - v2client "go-deploy/pkg/imp/harbor/sdk/v2.0/client" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/health" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/harbor" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/harbor/test" + v2client "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/health" ) var ( diff --git a/pkg/imp/harbor/harbor/test/server.go b/pkg/imp/harbor/harbor/test/server.go index 07f36809..0dc6a0b0 100644 --- a/pkg/imp/harbor/harbor/test/server.go +++ b/pkg/imp/harbor/harbor/test/server.go @@ -6,7 +6,7 @@ import ( "net/http" "net/http/httptest" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) const ( diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_parameters.go index 0ed7da43..7e2afef8 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewAddLabelParams creates a new AddLabelParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_responses.go index d3cc8428..03e271fd 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/add_label_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // AddLabelReader is a Reader for the AddLabel structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/copy_artifact_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/copy_artifact_responses.go index 0944afb9..e203d391 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/copy_artifact_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/copy_artifact_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CopyArtifactReader is a Reader for the CopyArtifact structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_parameters.go index 3949af6a..ca241a5e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateTagParams creates a new CreateTagParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_responses.go index 9657fcec..1e7fa15a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/create_tag_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateTagReader is a Reader for the CreateTag structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_artifact_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_artifact_responses.go index 258e31b2..49300dd7 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_artifact_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_artifact_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteArtifactReader is a Reader for the DeleteArtifact structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_tag_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_tag_responses.go index 757a9a51..7a031d66 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_tag_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/delete_tag_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteTagReader is a Reader for the DeleteTag structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/get_addition_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/get_addition_responses.go index 26bcd0b0..703c53ed 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/get_addition_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/get_addition_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetAdditionReader is a Reader for the GetAddition structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/get_artifact_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/get_artifact_responses.go index 51c89f54..4c9a6e19 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/get_artifact_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/get_artifact_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetArtifactReader is a Reader for the GetArtifact structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/get_vulnerabilities_addition_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/get_vulnerabilities_addition_responses.go index 76cc94a8..a6cb13fa 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/get_vulnerabilities_addition_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/get_vulnerabilities_addition_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetVulnerabilitiesAdditionReader is a Reader for the GetVulnerabilitiesAddition structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/list_accessories_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/list_accessories_responses.go index a742e53f..a3fca10a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/list_accessories_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/list_accessories_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListAccessoriesReader is a Reader for the ListAccessories structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/list_artifacts_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/list_artifacts_responses.go index a440f5dc..5136bae1 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/list_artifacts_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/list_artifacts_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListArtifactsReader is a Reader for the ListArtifacts structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/list_tags_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/list_tags_responses.go index e877f13c..e721265a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/list_tags_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/list_tags_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListTagsReader is a Reader for the ListTags structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/artifact/remove_label_responses.go b/pkg/imp/harbor/sdk/v2.0/client/artifact/remove_label_responses.go index 6760146b..a7e14775 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/artifact/remove_label_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/artifact/remove_label_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // RemoveLabelReader is a Reader for the RemoveLabel structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/auditlog/list_audit_logs_responses.go b/pkg/imp/harbor/sdk/v2.0/client/auditlog/list_audit_logs_responses.go index 62326e07..c7923596 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/auditlog/list_audit_logs_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/auditlog/list_audit_logs_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListAuditLogsReader is a Reader for the ListAuditLogs structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/configure/get_configurations_responses.go b/pkg/imp/harbor/sdk/v2.0/client/configure/get_configurations_responses.go index bdbb5695..0adc0b1c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/configure/get_configurations_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/configure/get_configurations_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetConfigurationsReader is a Reader for the GetConfigurations structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/configure/get_internalconfig_responses.go b/pkg/imp/harbor/sdk/v2.0/client/configure/get_internalconfig_responses.go index decae8a6..549225e5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/configure/get_internalconfig_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/configure/get_internalconfig_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetInternalconfigReader is a Reader for the GetInternalconfig structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/configure/update_configurations_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/configure/update_configurations_parameters.go index 5a9f714c..c6738d86 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/configure/update_configurations_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/configure/update_configurations_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateConfigurationsParams creates a new UpdateConfigurationsParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_parameters.go index 3982203f..287c4616 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateGCScheduleParams creates a new CreateGCScheduleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_responses.go index 471b4e04..9106b88f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/create_gc_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateGCScheduleReader is a Reader for the CreateGCSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_history_responses.go b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_history_responses.go index eb249b9b..ffb43296 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_history_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_history_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetGCHistoryReader is a Reader for the GetGCHistory structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_log_responses.go b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_log_responses.go index b6a2215c..6556d4d9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_log_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_log_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetGCLogReader is a Reader for the GetGCLog structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_responses.go b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_responses.go index fa4724cd..b2b41b23 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetGCReader is a Reader for the GetGC structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_schedule_responses.go index 49b78599..50f1b535 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/get_gc_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetGCScheduleReader is a Reader for the GetGCSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/stop_gc_responses.go b/pkg/imp/harbor/sdk/v2.0/client/gc/stop_gc_responses.go index 34f502d1..982d3619 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/stop_gc_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/stop_gc_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StopGCReader is a Reader for the StopGC structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_parameters.go index 89df4b76..9dc90d86 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateGCScheduleParams creates a new UpdateGCScheduleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_responses.go index 7c2818f3..6340b160 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/gc/update_gc_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateGCScheduleReader is a Reader for the UpdateGCSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/harbor_api_client.go b/pkg/imp/harbor/sdk/v2.0/client/harbor_api_client.go index a90a4428..2adbe071 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/harbor_api_client.go +++ b/pkg/imp/harbor/sdk/v2.0/client/harbor_api_client.go @@ -13,45 +13,45 @@ import ( rtclient "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/artifact" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/auditlog" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/configure" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/gc" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/health" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/icon" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/immutable" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/jobservice" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/label" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/ldap" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/member" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/oidc" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/permissions" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/ping" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/preheat" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/project_metadata" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/purge" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/quota" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/registry" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/replication" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/repository" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/retention" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/robot" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/robotv1" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/scan" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/scan_all" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/scan_data_export" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/scanner" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/schedule" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/search" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/securityhub" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/statistic" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/systeminfo" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/user" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/usergroup" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhook" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhookjob" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/artifact" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/auditlog" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/configure" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/gc" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/health" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/icon" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/immutable" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/jobservice" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/label" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/ldap" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/member" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/oidc" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/permissions" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/ping" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/preheat" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/project_metadata" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/purge" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/quota" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/registry" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/replication" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/repository" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/retention" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robot" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robotv1" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/scan" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/scan_all" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/scan_data_export" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/scanner" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/schedule" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/search" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/securityhub" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/statistic" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/systeminfo" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/user" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/usergroup" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhook" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhookjob" ) const ( diff --git a/pkg/imp/harbor/sdk/v2.0/client/health/get_health_responses.go b/pkg/imp/harbor/sdk/v2.0/client/health/get_health_responses.go index 8060bca6..f0816161 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/health/get_health_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/health/get_health_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetHealthReader is a Reader for the GetHealth structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/icon/get_icon_responses.go b/pkg/imp/harbor/sdk/v2.0/client/icon/get_icon_responses.go index 82021b4f..23841229 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/icon/get_icon_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/icon/get_icon_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetIconReader is a Reader for the GetIcon structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_parameters.go index 281c0736..b43b3059 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateImmuRuleParams creates a new CreateImmuRuleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_responses.go index 973f7ce9..1baa44f0 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/immutable/create_immu_rule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateImmuRuleReader is a Reader for the CreateImmuRule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/immutable/delete_immu_rule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/immutable/delete_immu_rule_responses.go index 3e93e828..83cddeca 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/immutable/delete_immu_rule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/immutable/delete_immu_rule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteImmuRuleReader is a Reader for the DeleteImmuRule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/immutable/list_immu_rules_responses.go b/pkg/imp/harbor/sdk/v2.0/client/immutable/list_immu_rules_responses.go index 1ce68ac6..cc8c2a99 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/immutable/list_immu_rules_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/immutable/list_immu_rules_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListImmuRulesReader is a Reader for the ListImmuRules structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_parameters.go index b0eb5de2..0573dd1f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateImmuRuleParams creates a new UpdateImmuRuleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_responses.go index 6338374d..c45bc8b1 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/immutable/update_immu_rule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateImmuRuleReader is a Reader for the UpdateImmuRule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_get_job_log_responses.go b/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_get_job_log_responses.go index 370b3fcf..3f2b84d3 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_get_job_log_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_get_job_log_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ActionGetJobLogReader is a Reader for the ActionGetJobLog structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_parameters.go index 7f595a71..e21155ad 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewActionPendingJobsParams creates a new ActionPendingJobsParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_responses.go b/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_responses.go index daeb542d..e66c2696 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/jobservice/action_pending_jobs_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ActionPendingJobsReader is a Reader for the ActionPendingJobs structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_worker_pools_responses.go b/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_worker_pools_responses.go index 187b4116..70f99c55 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_worker_pools_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_worker_pools_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetWorkerPoolsReader is a Reader for the GetWorkerPools structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_workers_responses.go b/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_workers_responses.go index 12d0c471..49551427 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_workers_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/jobservice/get_workers_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetWorkersReader is a Reader for the GetWorkers structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/jobservice/list_job_queues_responses.go b/pkg/imp/harbor/sdk/v2.0/client/jobservice/list_job_queues_responses.go index 42d940b0..d2d69d99 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/jobservice/list_job_queues_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/jobservice/list_job_queues_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListJobQueuesReader is a Reader for the ListJobQueues structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/jobservice/stop_running_job_responses.go b/pkg/imp/harbor/sdk/v2.0/client/jobservice/stop_running_job_responses.go index a0f36fbd..d337239e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/jobservice/stop_running_job_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/jobservice/stop_running_job_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StopRunningJobReader is a Reader for the StopRunningJob structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/label/create_label_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/label/create_label_parameters.go index 73b8433d..c8cffa27 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/label/create_label_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/label/create_label_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateLabelParams creates a new CreateLabelParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/label/create_label_responses.go b/pkg/imp/harbor/sdk/v2.0/client/label/create_label_responses.go index abbbb147..bf525ad5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/label/create_label_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/label/create_label_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateLabelReader is a Reader for the CreateLabel structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/label/delete_label_responses.go b/pkg/imp/harbor/sdk/v2.0/client/label/delete_label_responses.go index c3d1086d..590c7c76 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/label/delete_label_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/label/delete_label_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteLabelReader is a Reader for the DeleteLabel structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/label/get_label_by_id_responses.go b/pkg/imp/harbor/sdk/v2.0/client/label/get_label_by_id_responses.go index d3d26d3b..985fad6e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/label/get_label_by_id_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/label/get_label_by_id_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetLabelByIDReader is a Reader for the GetLabelByID structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/label/list_labels_responses.go b/pkg/imp/harbor/sdk/v2.0/client/label/list_labels_responses.go index 25eec92b..eedfbe4d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/label/list_labels_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/label/list_labels_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListLabelsReader is a Reader for the ListLabels structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/label/update_label_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/label/update_label_parameters.go index 384258b1..8a269ca0 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/label/update_label_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/label/update_label_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateLabelParams creates a new UpdateLabelParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/label/update_label_responses.go b/pkg/imp/harbor/sdk/v2.0/client/label/update_label_responses.go index d00db814..29aba8f9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/label/update_label_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/label/update_label_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateLabelReader is a Reader for the UpdateLabel structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_parameters.go index eb24a075..eaccf669 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewImportLdapUserParams creates a new ImportLdapUserParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_responses.go b/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_responses.go index f75aeea7..dae0e4e1 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/ldap/import_ldap_user_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ImportLdapUserReader is a Reader for the ImportLdapUser structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_parameters.go index a3043056..be89ffb9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewPingLdapParams creates a new PingLdapParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_responses.go b/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_responses.go index 35e9a49f..38c5bcb0 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/ldap/ping_ldap_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // PingLdapReader is a Reader for the PingLdap structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_group_responses.go b/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_group_responses.go index 1cd9cf38..cc663f91 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_group_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_group_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SearchLdapGroupReader is a Reader for the SearchLdapGroup structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_user_responses.go b/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_user_responses.go index 60806a6f..8b1948d1 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_user_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/ldap/search_ldap_user_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SearchLdapUserReader is a Reader for the SearchLdapUser structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_parameters.go index cb4144c6..3eafad57 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateProjectMemberParams creates a new CreateProjectMemberParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_responses.go b/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_responses.go index ab5a7b8d..15f7768e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/member/create_project_member_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateProjectMemberReader is a Reader for the CreateProjectMember structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/member/delete_project_member_responses.go b/pkg/imp/harbor/sdk/v2.0/client/member/delete_project_member_responses.go index a3540b0f..afc2b797 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/member/delete_project_member_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/member/delete_project_member_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteProjectMemberReader is a Reader for the DeleteProjectMember structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/member/get_project_member_responses.go b/pkg/imp/harbor/sdk/v2.0/client/member/get_project_member_responses.go index 1e042cf7..9b11444b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/member/get_project_member_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/member/get_project_member_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetProjectMemberReader is a Reader for the GetProjectMember structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/member/list_project_members_responses.go b/pkg/imp/harbor/sdk/v2.0/client/member/list_project_members_responses.go index 7425e293..e3bf289c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/member/list_project_members_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/member/list_project_members_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListProjectMembersReader is a Reader for the ListProjectMembers structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_parameters.go index 463b9c6c..bb5a8a03 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateProjectMemberParams creates a new UpdateProjectMemberParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_responses.go b/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_responses.go index f0d848f2..dc9bb400 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/member/update_project_member_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateProjectMemberReader is a Reader for the UpdateProjectMember structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/oidc/ping_oidc_responses.go b/pkg/imp/harbor/sdk/v2.0/client/oidc/ping_oidc_responses.go index 779a4081..73dedcf6 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/oidc/ping_oidc_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/oidc/ping_oidc_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // PingOIDCReader is a Reader for the PingOIDC structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/permissions/get_permissions_responses.go b/pkg/imp/harbor/sdk/v2.0/client/permissions/get_permissions_responses.go index 4e909184..c3c61961 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/permissions/get_permissions_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/permissions/get_permissions_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetPermissionsReader is a Reader for the GetPermissions structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_parameters.go index 235a7ec4..5b98d2ff 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateInstanceParams creates a new CreateInstanceParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_responses.go index 881e7335..0c165fe4 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_instance_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateInstanceReader is a Reader for the CreateInstance structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_parameters.go index 77c6fcd2..d61f529a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreatePolicyParams creates a new CreatePolicyParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_responses.go index a8bdddba..3ee010e6 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/create_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreatePolicyReader is a Reader for the CreatePolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_instance_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_instance_responses.go index f5873289..a27a2d67 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_instance_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_instance_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteInstanceReader is a Reader for the DeleteInstance structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_policy_responses.go index ad134bb5..7293ab21 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/delete_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeletePolicyReader is a Reader for the DeletePolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_execution_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_execution_responses.go index ab616399..77892603 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_execution_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_execution_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetExecutionReader is a Reader for the GetExecution structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_instance_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_instance_responses.go index 675c1dfd..42ffc889 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_instance_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_instance_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetInstanceReader is a Reader for the GetInstance structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_policy_responses.go index bb8cc6a2..3f7a0f29 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetPolicyReader is a Reader for the GetPolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_preheat_log_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_preheat_log_responses.go index 65167b98..1c43f5f2 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/get_preheat_log_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/get_preheat_log_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetPreheatLogReader is a Reader for the GetPreheatLog structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_executions_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_executions_responses.go index 6e932189..5de9c388 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_executions_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_executions_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListExecutionsReader is a Reader for the ListExecutions structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_instances_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_instances_responses.go index af192a62..8b4f4729 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_instances_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_instances_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListInstancesReader is a Reader for the ListInstances structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_policies_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_policies_responses.go index 9700e99d..423a391c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_policies_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_policies_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListPoliciesReader is a Reader for the ListPolicies structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_responses.go index 35f98ceb..cf928318 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListProvidersReader is a Reader for the ListProviders structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_under_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_under_project_responses.go index eb04278d..52235bad 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_under_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_providers_under_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListProvidersUnderProjectReader is a Reader for the ListProvidersUnderProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_tasks_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_tasks_responses.go index fdb1cf86..cbde99d9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/list_tasks_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/list_tasks_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListTasksReader is a Reader for the ListTasks structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_parameters.go index d91471f0..1cce10aa 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewManualPreheatParams creates a new ManualPreheatParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_responses.go index 90ba34e8..970df0c4 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/manual_preheat_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ManualPreheatReader is a Reader for the ManualPreheat structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_parameters.go index 39aa5463..d5e8e69a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewPingInstancesParams creates a new PingInstancesParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_responses.go index 90a59bbb..d5111d9b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/ping_instances_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // PingInstancesReader is a Reader for the PingInstances structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_parameters.go index fd2c8a7b..b9b9cbc5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewStopExecutionParams creates a new StopExecutionParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_responses.go index 4f711ab3..f8b66637 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/stop_execution_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StopExecutionReader is a Reader for the StopExecution structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_parameters.go index d86ec8c0..1c5ffc72 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateInstanceParams creates a new UpdateInstanceParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_responses.go index 8df4fba0..153e38a7 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_instance_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateInstanceReader is a Reader for the UpdateInstance structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_parameters.go index 303e463f..d610240c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdatePolicyParams creates a new UpdatePolicyParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_responses.go index 16edf4d6..c4aa6974 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/preheat/update_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdatePolicyReader is a Reader for the UpdatePolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/create_project_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/project/create_project_parameters.go index e2b2908e..2dab0bd1 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/create_project_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/create_project_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateProjectParams creates a new CreateProjectParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/create_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/create_project_responses.go index 6d4705a5..bee3c41d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/create_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/create_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateProjectReader is a Reader for the CreateProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/delete_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/delete_project_responses.go index fb34d363..0cd6f341 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/delete_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/delete_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteProjectReader is a Reader for the DeleteProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/get_logs_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/get_logs_responses.go index bac7952d..0b4686aa 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/get_logs_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/get_logs_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetLogsReader is a Reader for the GetLogs structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/get_project_deletable_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/get_project_deletable_responses.go index ae0d4f72..46e33b6b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/get_project_deletable_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/get_project_deletable_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetProjectDeletableReader is a Reader for the GetProjectDeletable structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/get_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/get_project_responses.go index b424bc65..b4a95ea2 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/get_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/get_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetProjectReader is a Reader for the GetProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/get_project_summary_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/get_project_summary_responses.go index 41bbaa96..0ad73eda 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/get_project_summary_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/get_project_summary_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetProjectSummaryReader is a Reader for the GetProjectSummary structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/get_scanner_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/get_scanner_of_project_responses.go index 4c5797cd..4ebbccd6 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/get_scanner_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/get_scanner_of_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetScannerOfProjectReader is a Reader for the GetScannerOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/head_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/head_project_responses.go index 616b3c97..20427d04 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/head_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/head_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // HeadProjectReader is a Reader for the HeadProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/list_projects_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/list_projects_responses.go index ac0e1bd3..8866245f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/list_projects_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/list_projects_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListProjectsReader is a Reader for the ListProjects structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/list_scanner_candidates_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/list_scanner_candidates_of_project_responses.go index 3d4a29ce..c9baf4fe 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/list_scanner_candidates_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/list_scanner_candidates_of_project_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListScannerCandidatesOfProjectReader is a Reader for the ListScannerCandidatesOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_parameters.go index 4a1790e2..fef3cc9b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewSetScannerOfProjectParams creates a new SetScannerOfProjectParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_responses.go index 1b7f63d2..fb69800d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/set_scanner_of_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SetScannerOfProjectReader is a Reader for the SetScannerOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/update_project_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/project/update_project_parameters.go index 4ffb5d89..ce164bfc 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/update_project_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/update_project_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateProjectParams creates a new UpdateProjectParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/project/update_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project/update_project_responses.go index 4994b895..0d20e95b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project/update_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project/update_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateProjectReader is a Reader for the UpdateProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/add_project_metadatas_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/add_project_metadatas_responses.go index 5f45d853..efe8d6e2 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/add_project_metadatas_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/add_project_metadatas_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // AddProjectMetadatasReader is a Reader for the AddProjectMetadatas structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/delete_project_metadata_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/delete_project_metadata_responses.go index c808a70c..d8a8eae6 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/delete_project_metadata_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/delete_project_metadata_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteProjectMetadataReader is a Reader for the DeleteProjectMetadata structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/get_project_metadata_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/get_project_metadata_responses.go index f8362688..7ca70493 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/get_project_metadata_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/get_project_metadata_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetProjectMetadataReader is a Reader for the GetProjectMetadata structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/list_project_metadatas_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/list_project_metadatas_responses.go index 01b12f2c..353fd44a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/list_project_metadatas_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/list_project_metadatas_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListProjectMetadatasReader is a Reader for the ListProjectMetadatas structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/update_project_metadata_responses.go b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/update_project_metadata_responses.go index 44cfe175..75cf5a98 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/project_metadata/update_project_metadata_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/project_metadata/update_project_metadata_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateProjectMetadataReader is a Reader for the UpdateProjectMetadata structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_parameters.go index 000adcf9..77cfdfed 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreatePurgeScheduleParams creates a new CreatePurgeScheduleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_responses.go index 6e7104ac..b60ab929 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/create_purge_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreatePurgeScheduleReader is a Reader for the CreatePurgeSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_history_responses.go b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_history_responses.go index 85f7fb6c..f95d1207 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_history_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_history_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetPurgeHistoryReader is a Reader for the GetPurgeHistory structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_log_responses.go b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_log_responses.go index 1c46f78a..fe5ddfba 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_log_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_log_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetPurgeJobLogReader is a Reader for the GetPurgeJobLog structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_responses.go b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_responses.go index 7e438c43..f3579045 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_job_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetPurgeJobReader is a Reader for the GetPurgeJob structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_schedule_responses.go index 261426de..201f9266 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/get_purge_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetPurgeScheduleReader is a Reader for the GetPurgeSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/stop_purge_responses.go b/pkg/imp/harbor/sdk/v2.0/client/purge/stop_purge_responses.go index d1d95fa3..46b9a8f6 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/stop_purge_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/stop_purge_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StopPurgeReader is a Reader for the StopPurge structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_parameters.go index 7793b4a9..912056a9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdatePurgeScheduleParams creates a new UpdatePurgeScheduleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_responses.go index 485c8a6b..84a05e2c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/purge/update_purge_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdatePurgeScheduleReader is a Reader for the UpdatePurgeSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/quota/get_quota_responses.go b/pkg/imp/harbor/sdk/v2.0/client/quota/get_quota_responses.go index 22e8f119..aecbba6d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/quota/get_quota_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/quota/get_quota_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetQuotaReader is a Reader for the GetQuota structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/quota/list_quotas_responses.go b/pkg/imp/harbor/sdk/v2.0/client/quota/list_quotas_responses.go index 5e70239d..104f6c22 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/quota/list_quotas_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/quota/list_quotas_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListQuotasReader is a Reader for the ListQuotas structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_parameters.go index 9567a780..f738f24d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateQuotaParams creates a new UpdateQuotaParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_responses.go b/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_responses.go index 4f10005a..65d479f7 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/quota/update_quota_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateQuotaReader is a Reader for the UpdateQuota structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_parameters.go index b7c2baf8..9a9b06bf 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateRegistryParams creates a new CreateRegistryParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_responses.go index 213ebbba..d23212cb 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/create_registry_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateRegistryReader is a Reader for the CreateRegistry structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/delete_registry_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/delete_registry_responses.go index da7e2170..cf035cad 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/delete_registry_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/delete_registry_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteRegistryReader is a Reader for the DeleteRegistry structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_info_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_info_responses.go index f5a6e82d..554f3759 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_info_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_info_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRegistryInfoReader is a Reader for the GetRegistryInfo structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_responses.go index 0b6105c9..3787a1f1 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/get_registry_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRegistryReader is a Reader for the GetRegistry structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/list_registries_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/list_registries_responses.go index 86e6b4dc..e4daf4e1 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/list_registries_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/list_registries_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRegistriesReader is a Reader for the ListRegistries structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_infos_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_infos_responses.go index d96b7fcc..74d00fd3 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_infos_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_infos_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRegistryProviderInfosReader is a Reader for the ListRegistryProviderInfos structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_types_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_types_responses.go index 8851988f..f3b952ac 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_types_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/list_registry_provider_types_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRegistryProviderTypesReader is a Reader for the ListRegistryProviderTypes structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_parameters.go index a5c592bf..8321c918 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewPingRegistryParams creates a new PingRegistryParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_responses.go index 4e178a81..d0af2a59 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/ping_registry_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // PingRegistryReader is a Reader for the PingRegistry structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_parameters.go index af5da804..f8880759 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateRegistryParams creates a new UpdateRegistryParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_responses.go b/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_responses.go index 590de624..96e165ef 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/registry/update_registry_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateRegistryReader is a Reader for the UpdateRegistry structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_parameters.go index c0536926..1edca194 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateReplicationPolicyParams creates a new CreateReplicationPolicyParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_responses.go index 39d6d5c4..ffeffa7a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/create_replication_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateReplicationPolicyReader is a Reader for the CreateReplicationPolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/delete_replication_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/delete_replication_policy_responses.go index df2d827b..acddae7f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/delete_replication_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/delete_replication_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteReplicationPolicyReader is a Reader for the DeleteReplicationPolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_execution_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_execution_responses.go index a34f07b3..0268117f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_execution_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_execution_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetReplicationExecutionReader is a Reader for the GetReplicationExecution structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_log_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_log_responses.go index 4a052fa8..9a5158d3 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_log_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_log_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetReplicationLogReader is a Reader for the GetReplicationLog structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_policy_responses.go index 45d302aa..2b2b63a5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/get_replication_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetReplicationPolicyReader is a Reader for the GetReplicationPolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_executions_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_executions_responses.go index fee2757d..e31009fb 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_executions_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_executions_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListReplicationExecutionsReader is a Reader for the ListReplicationExecutions structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_policies_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_policies_responses.go index db8c0635..0746ae32 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_policies_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_policies_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListReplicationPoliciesReader is a Reader for the ListReplicationPolicies structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_tasks_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_tasks_responses.go index 5dc06ab2..05214a6d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_tasks_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/list_replication_tasks_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListReplicationTasksReader is a Reader for the ListReplicationTasks structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_parameters.go index 52a6e3c6..0e0fb272 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewStartReplicationParams creates a new StartReplicationParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_responses.go index 93f01202..55ea1bdd 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/start_replication_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StartReplicationReader is a Reader for the StartReplication structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/stop_replication_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/stop_replication_responses.go index c8e3349a..f8edec26 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/stop_replication_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/stop_replication_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StopReplicationReader is a Reader for the StopReplication structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_parameters.go index acd1a6b8..c4e2216e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateReplicationPolicyParams creates a new UpdateReplicationPolicyParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_responses.go index 43baf893..ba8ef044 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/replication/update_replication_policy_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateReplicationPolicyReader is a Reader for the UpdateReplicationPolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/repository/delete_repository_responses.go b/pkg/imp/harbor/sdk/v2.0/client/repository/delete_repository_responses.go index de5089c6..e4a32eec 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/repository/delete_repository_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/repository/delete_repository_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteRepositoryReader is a Reader for the DeleteRepository structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/repository/get_repository_responses.go b/pkg/imp/harbor/sdk/v2.0/client/repository/get_repository_responses.go index fec4b2b5..557a065a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/repository/get_repository_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/repository/get_repository_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRepositoryReader is a Reader for the GetRepository structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/repository/list_all_repositories_responses.go b/pkg/imp/harbor/sdk/v2.0/client/repository/list_all_repositories_responses.go index ef3dbc77..d027e1f0 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/repository/list_all_repositories_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/repository/list_all_repositories_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListAllRepositoriesReader is a Reader for the ListAllRepositories structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/repository/list_repositories_responses.go b/pkg/imp/harbor/sdk/v2.0/client/repository/list_repositories_responses.go index 92da9268..7183504c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/repository/list_repositories_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/repository/list_repositories_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRepositoriesReader is a Reader for the ListRepositories structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_parameters.go index 53bb3aff..a3ea6d1b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateRepositoryParams creates a new UpdateRepositoryParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_responses.go b/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_responses.go index fc6b1bc9..98841483 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/repository/update_repository_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateRepositoryReader is a Reader for the UpdateRepository structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_parameters.go index 42d3236e..c271d0ff 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateRetentionParams creates a new CreateRetentionParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_responses.go index 3b862f2c..d85db198 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/create_retention_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateRetentionReader is a Reader for the CreateRetention structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/delete_retention_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/delete_retention_responses.go index 48c32917..d509e4a9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/delete_retention_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/delete_retention_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteRetentionReader is a Reader for the DeleteRetention structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/get_rentenition_metadata_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/get_rentenition_metadata_responses.go index 429034ea..5ac6d790 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/get_rentenition_metadata_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/get_rentenition_metadata_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRentenitionMetadataReader is a Reader for the GetRentenitionMetadata structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_responses.go index 7a4babf0..4ff0cfcd 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRetentionReader is a Reader for the GetRetention structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_task_log_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_task_log_responses.go index 6ce2bc31..baf515f3 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_task_log_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/get_retention_task_log_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRetentionTaskLogReader is a Reader for the GetRetentionTaskLog structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_executions_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_executions_responses.go index 71f80f29..224fbf9b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_executions_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_executions_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRetentionExecutionsReader is a Reader for the ListRetentionExecutions structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_tasks_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_tasks_responses.go index e61a4717..fe5f5205 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_tasks_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/list_retention_tasks_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRetentionTasksReader is a Reader for the ListRetentionTasks structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/operate_retention_execution_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/operate_retention_execution_responses.go index 6588df71..1e5834c7 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/operate_retention_execution_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/operate_retention_execution_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // OperateRetentionExecutionReader is a Reader for the OperateRetentionExecution structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/trigger_retention_execution_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/trigger_retention_execution_responses.go index 32643b52..b51b7c6c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/trigger_retention_execution_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/trigger_retention_execution_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // TriggerRetentionExecutionReader is a Reader for the TriggerRetentionExecution structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_parameters.go index 159ffd47..2b6b120e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateRetentionParams creates a new UpdateRetentionParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_responses.go b/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_responses.go index 933eb446..a1d1a4df 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/retention/update_retention_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateRetentionReader is a Reader for the UpdateRetention structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_parameters.go index cea1a2a2..fab0e57d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateRobotParams creates a new CreateRobotParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_responses.go index f7e10b1b..ba5a9930 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/create_robot_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateRobotReader is a Reader for the CreateRobot structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/delete_robot_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robot/delete_robot_responses.go index 4c51a377..d2a0e53c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/delete_robot_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/delete_robot_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteRobotReader is a Reader for the DeleteRobot structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/get_robot_by_id_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robot/get_robot_by_id_responses.go index 7b4e5c8b..9f539fea 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/get_robot_by_id_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/get_robot_by_id_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRobotByIDReader is a Reader for the GetRobotByID structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/list_robot_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robot/list_robot_responses.go index abd41922..08c70191 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/list_robot_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/list_robot_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRobotReader is a Reader for the ListRobot structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_parameters.go index e786a849..0c75d96f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewRefreshSecParams creates a new RefreshSecParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_responses.go index c79e1ec4..71ad9bcf 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/refresh_sec_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // RefreshSecReader is a Reader for the RefreshSec structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_parameters.go index 7c905096..b01a0ee3 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateRobotParams creates a new UpdateRobotParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_responses.go index 5da7a552..166baa8c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robot/update_robot_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateRobotReader is a Reader for the UpdateRobot structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_parameters.go index 8593b446..43caeeb6 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateRobotV1Params creates a new CreateRobotV1Params object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_responses.go index 72221ae3..625c6f75 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robotv1/create_robot_v1_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateRobotV1Reader is a Reader for the CreateRobotV1 structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robotv1/delete_robot_v1_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robotv1/delete_robot_v1_responses.go index 663c0e35..79152e43 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robotv1/delete_robot_v1_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robotv1/delete_robot_v1_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteRobotV1Reader is a Reader for the DeleteRobotV1 structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robotv1/get_robot_by_id_v1_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robotv1/get_robot_by_id_v1_responses.go index 8338d0b0..8582f85a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robotv1/get_robot_by_id_v1_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robotv1/get_robot_by_id_v1_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetRobotByIDV1Reader is a Reader for the GetRobotByIDV1 structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robotv1/list_robot_v1_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robotv1/list_robot_v1_responses.go index df0962c3..e0327380 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robotv1/list_robot_v1_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robotv1/list_robot_v1_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListRobotV1Reader is a Reader for the ListRobotV1 structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_parameters.go index 5351a1cb..d0074759 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateRobotV1Params creates a new UpdateRobotV1Params object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_responses.go b/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_responses.go index dfee15ac..5fedfa73 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/robotv1/update_robot_v1_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateRobotV1Reader is a Reader for the UpdateRobotV1 structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan/get_report_log_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan/get_report_log_responses.go index d9c6add6..b5a64557 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan/get_report_log_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan/get_report_log_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetReportLogReader is a Reader for the GetReportLog structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan/scan_artifact_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan/scan_artifact_responses.go index 7b8b83a8..b2b84ab5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan/scan_artifact_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan/scan_artifact_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ScanArtifactReader is a Reader for the ScanArtifact structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan/stop_scan_artifact_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan/stop_scan_artifact_responses.go index bda9b220..785c8a5b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan/stop_scan_artifact_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan/stop_scan_artifact_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StopScanArtifactReader is a Reader for the StopScanArtifact structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_parameters.go index abe88c16..6293ebf6 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateScanAllScheduleParams creates a new CreateScanAllScheduleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_responses.go index ab6a0484..58a53daa 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/create_scan_all_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateScanAllScheduleReader is a Reader for the CreateScanAllSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scan_all_metrics_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scan_all_metrics_responses.go index db1a8032..9bc9b671 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scan_all_metrics_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scan_all_metrics_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetLatestScanAllMetricsReader is a Reader for the GetLatestScanAllMetrics structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scheduled_scan_all_metrics_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scheduled_scan_all_metrics_responses.go index b3f32ecb..e43cdcd2 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scheduled_scan_all_metrics_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_latest_scheduled_scan_all_metrics_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetLatestScheduledScanAllMetricsReader is a Reader for the GetLatestScheduledScanAllMetrics structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_scan_all_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_scan_all_schedule_responses.go index 82d36a6a..aaa82300 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_scan_all_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/get_scan_all_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetScanAllScheduleReader is a Reader for the GetScanAllSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/stop_scan_all_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/stop_scan_all_responses.go index 60715935..7f10f3f5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/stop_scan_all_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/stop_scan_all_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // StopScanAllReader is a Reader for the StopScanAll structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_parameters.go index cd713072..15a54525 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateScanAllScheduleParams creates a new UpdateScanAllScheduleParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_responses.go index 149c6760..be985ad5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_all/update_scan_all_schedule_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateScanAllScheduleReader is a Reader for the UpdateScanAllSchedule structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/download_scan_data_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/download_scan_data_responses.go index 19aa2873..d97a77a9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/download_scan_data_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/download_scan_data_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DownloadScanDataReader is a Reader for the DownloadScanData structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_parameters.go index 02ec7a5d..94ba157d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewExportScanDataParams creates a new ExportScanDataParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_responses.go index a09c2330..ef7fff0f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/export_scan_data_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ExportScanDataReader is a Reader for the ExportScanData structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_list_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_list_responses.go index 23639f03..3a8b4855 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_list_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_list_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetScanDataExportExecutionListReader is a Reader for the GetScanDataExportExecutionList structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_responses.go index 62a5fb6a..c4bcf746 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scan_data_export/get_scan_data_export_execution_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetScanDataExportExecutionReader is a Reader for the GetScanDataExportExecution structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_parameters.go index 25be1aca..31bce89c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateScannerParams creates a new CreateScannerParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_responses.go index 42de1d36..717a0b9f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/create_scanner_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateScannerReader is a Reader for the CreateScanner structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/delete_scanner_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/delete_scanner_responses.go index e47e51b3..785a499c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/delete_scanner_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/delete_scanner_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteScannerReader is a Reader for the DeleteScanner structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_metadata_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_metadata_responses.go index 7f01594b..7897002b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_metadata_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_metadata_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetScannerMetadataReader is a Reader for the GetScannerMetadata structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_responses.go index 9e453a49..ea7032ee 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/get_scanner_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetScannerReader is a Reader for the GetScanner structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/list_scanners_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/list_scanners_responses.go index cce3bdd5..2905f819 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/list_scanners_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/list_scanners_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListScannersReader is a Reader for the ListScanners structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_parameters.go index 336842a5..50f6288f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewPingScannerParams creates a new PingScannerParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_responses.go index c913840b..eb1bd0bc 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/ping_scanner_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // PingScannerReader is a Reader for the PingScanner structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_parameters.go index deff0fce..2b92050d 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewSetScannerAsDefaultParams creates a new SetScannerAsDefaultParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_responses.go index 1d7c365d..07cf88a0 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/set_scanner_as_default_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SetScannerAsDefaultReader is a Reader for the SetScannerAsDefault structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_parameters.go index c19b0eda..66e013f2 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateScannerParams creates a new UpdateScannerParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_responses.go b/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_responses.go index 7546e8ea..8b5861f2 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/scanner/update_scanner_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateScannerReader is a Reader for the UpdateScanner structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/schedule/get_schedule_paused_responses.go b/pkg/imp/harbor/sdk/v2.0/client/schedule/get_schedule_paused_responses.go index f6b87b25..258e126f 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/schedule/get_schedule_paused_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/schedule/get_schedule_paused_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetSchedulePausedReader is a Reader for the GetSchedulePaused structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/schedule/list_schedules_responses.go b/pkg/imp/harbor/sdk/v2.0/client/schedule/list_schedules_responses.go index 1608cef8..02922679 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/schedule/list_schedules_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/schedule/list_schedules_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListSchedulesReader is a Reader for the ListSchedules structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/search/search_responses.go b/pkg/imp/harbor/sdk/v2.0/client/search/search_responses.go index 1c8c76ff..16704a8e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/search/search_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/search/search_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SearchReader is a Reader for the Search structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/securityhub/get_security_summary_responses.go b/pkg/imp/harbor/sdk/v2.0/client/securityhub/get_security_summary_responses.go index 3ce324c7..44b0a945 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/securityhub/get_security_summary_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/securityhub/get_security_summary_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetSecuritySummaryReader is a Reader for the GetSecuritySummary structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/securityhub/list_vulnerabilities_responses.go b/pkg/imp/harbor/sdk/v2.0/client/securityhub/list_vulnerabilities_responses.go index 82ca1d26..178812ce 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/securityhub/list_vulnerabilities_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/securityhub/list_vulnerabilities_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListVulnerabilitiesReader is a Reader for the ListVulnerabilities structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/statistic/get_statistic_responses.go b/pkg/imp/harbor/sdk/v2.0/client/statistic/get_statistic_responses.go index ccbbe242..eae4b8be 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/statistic/get_statistic_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/statistic/get_statistic_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetStatisticReader is a Reader for the GetStatistic structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/get_system_cve_allowlist_responses.go b/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/get_system_cve_allowlist_responses.go index b6ce7a9a..baaa272c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/get_system_cve_allowlist_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/get_system_cve_allowlist_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetSystemCVEAllowlistReader is a Reader for the GetSystemCVEAllowlist structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_parameters.go index 9ff79933..60786d42 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewPutSystemCVEAllowlistParams creates a new PutSystemCVEAllowlistParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_responses.go b/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_responses.go index 6014b002..b7897a9b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/system_cve_allowlist/put_system_cve_allowlist_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // PutSystemCVEAllowlistReader is a Reader for the PutSystemCVEAllowlist structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_cert_responses.go b/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_cert_responses.go index ff6c3a6c..c70558d3 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_cert_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_cert_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetCertReader is a Reader for the GetCert structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_system_info_responses.go b/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_system_info_responses.go index b640cced..4b829582 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_system_info_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_system_info_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetSystemInfoReader is a Reader for the GetSystemInfo structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_volumes_responses.go b/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_volumes_responses.go index bcb818ec..9b156db7 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_volumes_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/systeminfo/get_volumes_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetVolumesReader is a Reader for the GetVolumes structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/create_user_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/user/create_user_parameters.go index 55b01c1c..0d056e5c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/create_user_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/create_user_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateUserParams creates a new CreateUserParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/create_user_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/create_user_responses.go index 980f270a..3f6ac9da 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/create_user_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/create_user_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateUserReader is a Reader for the CreateUser structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/delete_user_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/delete_user_responses.go index bbee3e58..8f4be07b 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/delete_user_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/delete_user_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteUserReader is a Reader for the DeleteUser structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_info_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_info_responses.go index 523189b3..c03d54cb 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_info_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_info_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetCurrentUserInfoReader is a Reader for the GetCurrentUserInfo structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_permissions_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_permissions_responses.go index 7f95dee2..74dbdee2 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_permissions_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/get_current_user_permissions_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetCurrentUserPermissionsReader is a Reader for the GetCurrentUserPermissions structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/get_user_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/get_user_responses.go index 23654639..ce4fd541 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/get_user_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/get_user_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetUserReader is a Reader for the GetUser structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/list_users_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/list_users_responses.go index 34f34dba..08f45ba9 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/list_users_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/list_users_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListUsersReader is a Reader for the ListUsers structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/search_users_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/search_users_responses.go index 90034aff..b0ee0e43 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/search_users_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/search_users_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SearchUsersReader is a Reader for the SearchUsers structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_parameters.go index 3f312a6e..bc2dcc1a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewSetCliSecretParams creates a new SetCliSecretParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_responses.go index f46b3735..2e4996c5 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/set_cli_secret_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SetCliSecretReader is a Reader for the SetCliSecret structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_parameters.go index 80102dd9..54701d12 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewSetUserSysAdminParams creates a new SetUserSysAdminParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_responses.go index 2a11c89d..13135b1e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/set_user_sys_admin_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SetUserSysAdminReader is a Reader for the SetUserSysAdmin structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_parameters.go index 8c534b72..9e44dc58 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateUserPasswordParams creates a new UpdateUserPasswordParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_responses.go index 018a60ab..0931b7fe 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_password_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateUserPasswordReader is a Reader for the UpdateUserPassword structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_parameters.go index 582e8830..75a2cae4 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateUserProfileParams creates a new UpdateUserProfileParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_responses.go b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_responses.go index 30c7ecdd..6b8aa05a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/user/update_user_profile_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateUserProfileReader is a Reader for the UpdateUserProfile structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_parameters.go index beaf072c..26263044 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_parameters.go @@ -15,7 +15,7 @@ import ( cr "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateUserGroupParams creates a new CreateUserGroupParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_responses.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_responses.go index 2b695562..ed455d77 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/create_user_group_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateUserGroupReader is a Reader for the CreateUserGroup structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/delete_user_group_responses.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/delete_user_group_responses.go index 2f1cf4a0..6d636a56 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/delete_user_group_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/delete_user_group_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteUserGroupReader is a Reader for the DeleteUserGroup structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/get_user_group_responses.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/get_user_group_responses.go index c257c528..42538c71 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/get_user_group_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/get_user_group_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetUserGroupReader is a Reader for the GetUserGroup structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/list_user_groups_responses.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/list_user_groups_responses.go index b9e21005..70670587 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/list_user_groups_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/list_user_groups_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListUserGroupsReader is a Reader for the ListUserGroups structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/search_user_groups_responses.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/search_user_groups_responses.go index 989d38c9..f0693b33 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/search_user_groups_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/search_user_groups_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // SearchUserGroupsReader is a Reader for the SearchUserGroups structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_parameters.go index 9abbe53b..d8c0fa83 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateUserGroupParams creates a new UpdateUserGroupParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_responses.go b/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_responses.go index dd6b9117..cfba7473 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/usergroup/update_user_group_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateUserGroupReader is a Reader for the UpdateUserGroup structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_parameters.go index fd712e96..cf6faa09 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewCreateWebhookPolicyOfProjectParams creates a new CreateWebhookPolicyOfProjectParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_responses.go index 1b6a49fb..a58fabdd 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/create_webhook_policy_of_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // CreateWebhookPolicyOfProjectReader is a Reader for the CreateWebhookPolicyOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/delete_webhook_policy_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/delete_webhook_policy_of_project_responses.go index a1a0cd1f..e2409fba 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/delete_webhook_policy_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/delete_webhook_policy_of_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // DeleteWebhookPolicyOfProjectReader is a Reader for the DeleteWebhookPolicyOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/get_logs_of_webhook_task_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/get_logs_of_webhook_task_responses.go index 8f071223..ff13049c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/get_logs_of_webhook_task_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/get_logs_of_webhook_task_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetLogsOfWebhookTaskReader is a Reader for the GetLogsOfWebhookTask structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/get_supported_event_types_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/get_supported_event_types_responses.go index 803fef83..f637d160 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/get_supported_event_types_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/get_supported_event_types_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetSupportedEventTypesReader is a Reader for the GetSupportedEventTypes structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/get_webhook_policy_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/get_webhook_policy_of_project_responses.go index 43db065f..587e882c 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/get_webhook_policy_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/get_webhook_policy_of_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // GetWebhookPolicyOfProjectReader is a Reader for the GetWebhookPolicyOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/last_trigger_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/last_trigger_responses.go index 82656805..6af83258 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/last_trigger_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/last_trigger_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // LastTriggerReader is a Reader for the LastTrigger structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/list_executions_of_webhook_policy_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/list_executions_of_webhook_policy_responses.go index 2d2c2620..14d2587e 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/list_executions_of_webhook_policy_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/list_executions_of_webhook_policy_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListExecutionsOfWebhookPolicyReader is a Reader for the ListExecutionsOfWebhookPolicy structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/list_tasks_of_webhook_execution_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/list_tasks_of_webhook_execution_responses.go index d1600a08..a0c3569a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/list_tasks_of_webhook_execution_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/list_tasks_of_webhook_execution_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListTasksOfWebhookExecutionReader is a Reader for the ListTasksOfWebhookExecution structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/list_webhook_policies_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/list_webhook_policies_of_project_responses.go index d3415f0d..fbd3e439 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/list_webhook_policies_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/list_webhook_policies_of_project_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListWebhookPoliciesOfProjectReader is a Reader for the ListWebhookPoliciesOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_parameters.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_parameters.go index 79a519aa..1f1c5a03 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_parameters.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_parameters.go @@ -16,7 +16,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // NewUpdateWebhookPolicyOfProjectParams creates a new UpdateWebhookPolicyOfProjectParams object, diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_responses.go index 64a1d5a9..dcac716a 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhook/update_webhook_policy_of_project_responses.go @@ -12,7 +12,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // UpdateWebhookPolicyOfProjectReader is a Reader for the UpdateWebhookPolicyOfProject structure. diff --git a/pkg/imp/harbor/sdk/v2.0/client/webhookjob/list_webhook_jobs_responses.go b/pkg/imp/harbor/sdk/v2.0/client/webhookjob/list_webhook_jobs_responses.go index 136d2268..a9b6d764 100644 --- a/pkg/imp/harbor/sdk/v2.0/client/webhookjob/list_webhook_jobs_responses.go +++ b/pkg/imp/harbor/sdk/v2.0/client/webhookjob/list_webhook_jobs_responses.go @@ -14,7 +14,7 @@ import ( "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" ) // ListWebhookJobsReader is a Reader for the ListWebhookJobs structure. diff --git a/pkg/imp/kubevirt/kubevirt/clientset.go b/pkg/imp/kubevirt/kubevirt/clientset.go index 6b5ab984..c0d5eae3 100644 --- a/pkg/imp/kubevirt/kubevirt/clientset.go +++ b/pkg/imp/kubevirt/kubevirt/clientset.go @@ -4,8 +4,8 @@ package kubevirt import ( "fmt" - kubevirtv1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1" - snapshotv1alpha1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1" + kubevirtv1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1" + snapshotv1alpha1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1" "net/http" discovery "k8s.io/client-go/discovery" diff --git a/pkg/imp/kubevirt/kubevirt/fake/clientset_generated.go b/pkg/imp/kubevirt/kubevirt/fake/clientset_generated.go index 22fdb74d..c21f1e36 100644 --- a/pkg/imp/kubevirt/kubevirt/fake/clientset_generated.go +++ b/pkg/imp/kubevirt/kubevirt/fake/clientset_generated.go @@ -3,11 +3,11 @@ package fake import ( - clientset "go-deploy/pkg/imp/kubevirt/kubevirt" - kubevirtv1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1" - fakekubevirtv1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1/fake" - snapshotv1alpha1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1" - fakesnapshotv1alpha1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/fake" + clientset "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt" + kubevirtv1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1" + fakekubevirtv1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1/fake" + snapshotv1alpha1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1" + fakesnapshotv1alpha1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/core_client.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/core_client.go index ef4703d9..5113dc35 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/core_client.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/core_client.go @@ -3,7 +3,7 @@ package v1 import ( - "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "net/http" rest "k8s.io/client-go/rest" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/fake/fake_core_client.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/fake/fake_core_client.go index 5a8f0144..37c7b596 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/fake/fake_core_client.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/fake/fake_core_client.go @@ -3,7 +3,7 @@ package fake import ( - v1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1" + v1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/core/v1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/kubevirt.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/kubevirt.go index b6b5f280..5f349691 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/kubevirt.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/kubevirt.go @@ -4,7 +4,7 @@ package v1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachine.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachine.go index ecb96779..8e916082 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachine.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachine.go @@ -4,7 +4,7 @@ package v1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstance.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstance.go index 173963ab..fca4d5d5 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstance.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstance.go @@ -4,7 +4,7 @@ package v1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancemigration.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancemigration.go index dcf3529c..79376afd 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancemigration.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancemigration.go @@ -4,7 +4,7 @@ package v1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancepreset.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancepreset.go index d5f6ddec..fb87f2fd 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancepreset.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancepreset.go @@ -4,7 +4,7 @@ package v1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancereplicaset.go b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancereplicaset.go index d512f68a..6c1367a0 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancereplicaset.go +++ b/pkg/imp/kubevirt/kubevirt/typed/core/v1/virtualmachineinstancereplicaset.go @@ -4,7 +4,7 @@ package v1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/fake/fake_snapshot_client.go b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/fake/fake_snapshot_client.go index 2a70a760..ce658e28 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/fake/fake_snapshot_client.go +++ b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/fake/fake_snapshot_client.go @@ -3,7 +3,7 @@ package fake import ( - v1alpha1 "go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1" + v1alpha1 "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" diff --git a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/snapshot_client.go b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/snapshot_client.go index 782523be..d0eb14c4 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/snapshot_client.go +++ b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/snapshot_client.go @@ -3,7 +3,7 @@ package v1alpha1 import ( - "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "net/http" rest "k8s.io/client-go/rest" diff --git a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinerestore.go b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinerestore.go index 1ce130a6..a6527c39 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinerestore.go +++ b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinerestore.go @@ -4,7 +4,7 @@ package v1alpha1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshot.go b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshot.go index fb982183..d92002d8 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshot.go +++ b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshot.go @@ -4,7 +4,7 @@ package v1alpha1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshotcontent.go b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshotcontent.go index f3e46e4d..a1a3f524 100644 --- a/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshotcontent.go +++ b/pkg/imp/kubevirt/kubevirt/typed/snapshot/v1alpha1/virtualmachinesnapshotcontent.go @@ -4,7 +4,7 @@ package v1alpha1 import ( "context" - scheme "go-deploy/pkg/imp/kubevirt/kubevirt/scheme" + scheme "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt/scheme" "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/intializer/system_services.go b/pkg/intializer/system_services.go index e12d175f..5cc62f4e 100644 --- a/pkg/intializer/system_services.go +++ b/pkg/intializer/system_services.go @@ -3,10 +3,10 @@ package intializer import ( "errors" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/pkg/config" - "go-deploy/service" - sErrors "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" ) // EnsureSystemDeploymentsExists ensures that the deployments related to the system are created. diff --git a/pkg/intializer/test.go b/pkg/intializer/test.go index 70a616fc..41b75073 100644 --- a/pkg/intializer/test.go +++ b/pkg/intializer/test.go @@ -4,18 +4,18 @@ import ( "errors" "fmt" "github.com/google/uuid" - "go-deploy/models/mode" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/deployment_repo" - rErrors "go-deploy/pkg/db/resources/errors" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/team_repo" - "go-deploy/pkg/db/resources/user_repo" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" - "go-deploy/service" + "github.com/kthcloud/go-deploy/models/mode" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + rErrors "github.com/kthcloud/go-deploy/pkg/db/resources/errors" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/team_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service" "time" ) diff --git a/pkg/intializer/vm_port.go b/pkg/intializer/vm_port.go index 499926e6..85432eb1 100644 --- a/pkg/intializer/vm_port.go +++ b/pkg/intializer/vm_port.go @@ -1,10 +1,10 @@ package intializer import ( - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/vm_port_repo" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_port_repo" + "github.com/kthcloud/go-deploy/pkg/log" "strconv" ) diff --git a/pkg/jobs/job_definition.go b/pkg/jobs/job_definition.go index d177ebf0..46aa47b3 100644 --- a/pkg/jobs/job_definition.go +++ b/pkg/jobs/job_definition.go @@ -1,10 +1,10 @@ package jobs import ( - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/jobs/utils" - "go-deploy/pkg/jobs/v2" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/jobs/utils" + "github.com/kthcloud/go-deploy/pkg/jobs/v2" ) // JobDefinition is a definition of a job. diff --git a/pkg/jobs/runner.go b/pkg/jobs/runner.go index 8ec0731f..e5c47053 100644 --- a/pkg/jobs/runner.go +++ b/pkg/jobs/runner.go @@ -3,10 +3,10 @@ package jobs import ( "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/log" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/utils" "math" "strings" "time" diff --git a/pkg/jobs/utils/utils.go b/pkg/jobs/utils/utils.go index 845861bb..290e2029 100644 --- a/pkg/jobs/utils/utils.go +++ b/pkg/jobs/utils/utils.go @@ -4,12 +4,12 @@ import ( "context" "fmt" "github.com/mitchellh/mapstructure" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service/core" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "golang.org/x/exp/slices" diff --git a/pkg/jobs/v2/deployment_jobs.go b/pkg/jobs/v2/deployment_jobs.go index 806ed8cb..a996a9f1 100644 --- a/pkg/jobs/v2/deployment_jobs.go +++ b/pkg/jobs/v2/deployment_jobs.go @@ -5,16 +5,16 @@ import ( "errors" "fmt" "github.com/mitchellh/mapstructure" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/job_repo" - jErrors "go-deploy/pkg/jobs/errors" - "go-deploy/pkg/jobs/utils" - "go-deploy/pkg/log" - "go-deploy/pkg/services/confirm" - "go-deploy/service" - sErrors "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + jErrors "github.com/kthcloud/go-deploy/pkg/jobs/errors" + "github.com/kthcloud/go-deploy/pkg/jobs/utils" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services/confirm" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" "time" ) diff --git a/pkg/jobs/v2/sm_jobs.go b/pkg/jobs/v2/sm_jobs.go index fccbcee4..50857981 100644 --- a/pkg/jobs/v2/sm_jobs.go +++ b/pkg/jobs/v2/sm_jobs.go @@ -5,14 +5,14 @@ import ( "errors" "fmt" "github.com/mitchellh/mapstructure" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/sm_repo" - jErrors "go-deploy/pkg/jobs/errors" - "go-deploy/pkg/jobs/utils" - "go-deploy/pkg/log" - "go-deploy/service" - sErrors "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" + jErrors "github.com/kthcloud/go-deploy/pkg/jobs/errors" + "github.com/kthcloud/go-deploy/pkg/jobs/utils" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" "time" ) diff --git a/pkg/jobs/v2/vm_jobs.go b/pkg/jobs/v2/vm_jobs.go index da012320..149833e4 100644 --- a/pkg/jobs/v2/vm_jobs.go +++ b/pkg/jobs/v2/vm_jobs.go @@ -5,17 +5,17 @@ import ( "errors" "fmt" "github.com/mitchellh/mapstructure" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/vm_repo" - jErrors "go-deploy/pkg/jobs/errors" - "go-deploy/pkg/jobs/utils" - "go-deploy/pkg/log" - "go-deploy/pkg/services/confirm" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + jErrors "github.com/kthcloud/go-deploy/pkg/jobs/errors" + "github.com/kthcloud/go-deploy/pkg/jobs/utils" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services/confirm" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" "time" ) diff --git a/pkg/log/log.go b/pkg/log/log.go index a3069785..9150afc6 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -1,7 +1,7 @@ package log import ( - "go-deploy/models/mode" + "github.com/kthcloud/go-deploy/models/mode" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) diff --git a/pkg/metrics/setup.go b/pkg/metrics/setup.go index cf00b68b..023ab994 100644 --- a/pkg/metrics/setup.go +++ b/pkg/metrics/setup.go @@ -3,8 +3,8 @@ package metrics import ( "fmt" "github.com/penglongli/gin-metrics/ginmetrics" - "go-deploy/pkg/db/key_value" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/pkg/db/key_value" + "github.com/kthcloud/go-deploy/utils" "strconv" ) diff --git a/pkg/services/cleaner/service.go b/pkg/services/cleaner/service.go index fa38b54f..ecd75781 100644 --- a/pkg/services/cleaner/service.go +++ b/pkg/services/cleaner/service.go @@ -2,9 +2,9 @@ package cleaner import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) // Setup starts the cleaners. diff --git a/pkg/services/cleaner/stale_resource_cleaner.go b/pkg/services/cleaner/stale_resource_cleaner.go index 40ed2ba7..549bbaf9 100644 --- a/pkg/services/cleaner/stale_resource_cleaner.go +++ b/pkg/services/cleaner/stale_resource_cleaner.go @@ -1,15 +1,15 @@ package cleaner import ( - bodyV2 "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" - "go-deploy/service" + bodyV2 "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/service" "time" ) diff --git a/pkg/services/common.go b/pkg/services/common.go index 0489c503..f9d2bd58 100644 --- a/pkg/services/common.go +++ b/pkg/services/common.go @@ -1,8 +1,8 @@ package services import ( - "go-deploy/pkg/db/resources/worker_status_repo" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/db/resources/worker_status_repo" + "github.com/kthcloud/go-deploy/pkg/log" ) // ReportUp reports that a worker is up. diff --git a/pkg/services/confirm/common.go b/pkg/services/confirm/common.go index 98a3ec02..37e36cc7 100644 --- a/pkg/services/confirm/common.go +++ b/pkg/services/confirm/common.go @@ -3,9 +3,9 @@ package confirm import ( "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/vm_port_repo" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_port_repo" "net" ) diff --git a/pkg/services/confirm/deployment_confirmer.go b/pkg/services/confirm/deployment_confirmer.go index ab5f607f..46aeba54 100644 --- a/pkg/services/confirm/deployment_confirmer.go +++ b/pkg/services/confirm/deployment_confirmer.go @@ -1,10 +1,10 @@ package confirm import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/log" "golang.org/x/exp/slices" ) diff --git a/pkg/services/confirm/domain_confirmer.go b/pkg/services/confirm/domain_confirmer.go index ea364ecf..9cc4df01 100644 --- a/pkg/services/confirm/domain_confirmer.go +++ b/pkg/services/confirm/domain_confirmer.go @@ -1,11 +1,11 @@ package confirm import ( - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" ) // CustomDomainConfirmer is a worker that confirms custom domain setup. diff --git a/pkg/services/confirm/service.go b/pkg/services/confirm/service.go index a17a1966..5d6d2312 100644 --- a/pkg/services/confirm/service.go +++ b/pkg/services/confirm/service.go @@ -2,9 +2,9 @@ package confirm import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) // Setup starts the confirmers. diff --git a/pkg/services/confirm/sm_confirmer.go b/pkg/services/confirm/sm_confirmer.go index da089f9e..3949a093 100644 --- a/pkg/services/confirm/sm_confirmer.go +++ b/pkg/services/confirm/sm_confirmer.go @@ -1,10 +1,10 @@ package confirm import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/sm_repo" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" + "github.com/kthcloud/go-deploy/pkg/log" "golang.org/x/exp/slices" ) diff --git a/pkg/services/confirm/subsystems.go b/pkg/services/confirm/subsystems.go index 53721538..a09e33af 100644 --- a/pkg/services/confirm/subsystems.go +++ b/pkg/services/confirm/subsystems.go @@ -1,6 +1,6 @@ package confirm -import "go-deploy/models/model" +import "github.com/kthcloud/go-deploy/models/model" // getDeploymentDeletedConfirmers gets the confirmers for deployment deletion. func getDeploymentDeletedConfirmers() []func(*model.Deployment) (bool, error) { diff --git a/pkg/services/confirm/vm_confirmer.go b/pkg/services/confirm/vm_confirmer.go index fe8e6e7c..516aa8dc 100644 --- a/pkg/services/confirm/vm_confirmer.go +++ b/pkg/services/confirm/vm_confirmer.go @@ -1,10 +1,10 @@ package confirm import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" "golang.org/x/exp/slices" ) diff --git a/pkg/services/job_execute/job_fetcher.go b/pkg/services/job_execute/job_fetcher.go index 9bd79c28..7fbb3a3a 100644 --- a/pkg/services/job_execute/job_fetcher.go +++ b/pkg/services/job_execute/job_fetcher.go @@ -1,8 +1,8 @@ package job_execute import ( - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/jobs" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/jobs" ) // JobFetcher is a worker that fetches new jobs from the database and runs them. diff --git a/pkg/services/job_execute/service.go b/pkg/services/job_execute/service.go index 9c4c201c..602773f1 100644 --- a/pkg/services/job_execute/service.go +++ b/pkg/services/job_execute/service.go @@ -2,9 +2,9 @@ package job_execute import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) // Setup starts the job workers. diff --git a/pkg/services/job_schedule/deployment_job_scheduler.go b/pkg/services/job_schedule/deployment_job_scheduler.go index a19f3e20..f3fd3684 100644 --- a/pkg/services/job_schedule/deployment_job_scheduler.go +++ b/pkg/services/job_schedule/deployment_job_scheduler.go @@ -2,11 +2,11 @@ package job_schedule import ( "github.com/google/uuid" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" ) // DeploymentRepairScheduler is a worker that repairs deployments. diff --git a/pkg/services/job_schedule/service.go b/pkg/services/job_schedule/service.go index 49718daf..b9f2a346 100644 --- a/pkg/services/job_schedule/service.go +++ b/pkg/services/job_schedule/service.go @@ -2,9 +2,9 @@ package job_schedule import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) // Setup starts job schedulers diff --git a/pkg/services/job_schedule/sm_job_scheduler.go b/pkg/services/job_schedule/sm_job_scheduler.go index 9c7133ee..1cca9d8f 100644 --- a/pkg/services/job_schedule/sm_job_scheduler.go +++ b/pkg/services/job_schedule/sm_job_scheduler.go @@ -2,11 +2,11 @@ package job_schedule import ( "github.com/google/uuid" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/sm_repo" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" ) // SmRepairScheduler is a worker that repairs storage managers. diff --git a/pkg/services/job_schedule/vm_job_scheduler.go b/pkg/services/job_schedule/vm_job_scheduler.go index 5fae1c18..3a59f547 100644 --- a/pkg/services/job_schedule/vm_job_scheduler.go +++ b/pkg/services/job_schedule/vm_job_scheduler.go @@ -2,11 +2,11 @@ package job_schedule import ( "github.com/google/uuid" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" ) // VmRepairScheduler is a worker that repairs VMs. diff --git a/pkg/services/logger/pod_logger.go b/pkg/services/logger/pod_logger.go index 79b4d4e6..9195e945 100644 --- a/pkg/services/logger/pod_logger.go +++ b/pkg/services/logger/pod_logger.go @@ -5,17 +5,17 @@ import ( "encoding/json" "errors" "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/key_value" - "go-deploy/pkg/db/message_queue" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/utils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/key_value" + "github.com/kthcloud/go-deploy/pkg/db/message_queue" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/utils" "os" "time" ) diff --git a/pkg/services/logger/pod_logger_control.go b/pkg/services/logger/pod_logger_control.go index 7cb45691..486fb307 100644 --- a/pkg/services/logger/pod_logger_control.go +++ b/pkg/services/logger/pod_logger_control.go @@ -3,14 +3,14 @@ package logger import ( "context" "fmt" - configModels "go-deploy/models/config" - "go-deploy/pkg/config" - "go-deploy/pkg/db/key_value" - "go-deploy/pkg/db/message_queue" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/service" - "go-deploy/utils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/key_value" + "github.com/kthcloud/go-deploy/pkg/db/message_queue" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/utils" "time" ) diff --git a/pkg/services/logger/service.go b/pkg/services/logger/service.go index 58f1352a..0cb98fe1 100644 --- a/pkg/services/logger/service.go +++ b/pkg/services/logger/service.go @@ -2,9 +2,9 @@ package logger import ( "context" - "go-deploy/pkg/db/key_value" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/db/key_value" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" "strings" "time" ) diff --git a/pkg/services/metrics_update/metric_updater.go b/pkg/services/metrics_update/metric_updater.go index fe002b4d..1bc8b56c 100644 --- a/pkg/services/metrics_update/metric_updater.go +++ b/pkg/services/metrics_update/metric_updater.go @@ -2,12 +2,12 @@ package metrics_update import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/key_value" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/pkg/db/resources/user_repo" - "go-deploy/pkg/metrics" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/key_value" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + "github.com/kthcloud/go-deploy/pkg/metrics" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/pkg/services/metrics_update/service.go b/pkg/services/metrics_update/service.go index 4f9dda09..ffafdcdb 100644 --- a/pkg/services/metrics_update/service.go +++ b/pkg/services/metrics_update/service.go @@ -2,9 +2,9 @@ package metrics_update import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) // Setup starts the metrics updaters. diff --git a/pkg/services/status_update/common.go b/pkg/services/status_update/common.go index 5983f8a0..2dd2b27b 100644 --- a/pkg/services/status_update/common.go +++ b/pkg/services/status_update/common.go @@ -2,9 +2,9 @@ package status_update import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/utils" "net/http" "strings" ) diff --git a/pkg/services/status_update/deployment_status_fetcher.go b/pkg/services/status_update/deployment_status_fetcher.go index 32f68fa8..5e2147f9 100644 --- a/pkg/services/status_update/deployment_status_fetcher.go +++ b/pkg/services/status_update/deployment_status_fetcher.go @@ -1,11 +1,11 @@ package status_update import ( - "go-deploy/models/model" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/service" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/service" ) func DeploymentStatusFetcher() error { diff --git a/pkg/services/status_update/deployment_status_listener.go b/pkg/services/status_update/deployment_status_listener.go index 536fe81d..2ade155b 100644 --- a/pkg/services/status_update/deployment_status_listener.go +++ b/pkg/services/status_update/deployment_status_listener.go @@ -3,14 +3,14 @@ package status_update import ( "context" "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/v2/deployments/k8s_service" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/v2/deployments/k8s_service" ) func DeploymentStatusListener(ctx context.Context) error { diff --git a/pkg/services/status_update/service.go b/pkg/services/status_update/service.go index 32787bdf..36ee9f9f 100644 --- a/pkg/services/status_update/service.go +++ b/pkg/services/status_update/service.go @@ -2,9 +2,9 @@ package status_update import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) // Setup starts the status updaters. diff --git a/pkg/services/status_update/vm_status_fetcher.go b/pkg/services/status_update/vm_status_fetcher.go index a5de93f8..c159c674 100644 --- a/pkg/services/status_update/vm_status_fetcher.go +++ b/pkg/services/status_update/vm_status_fetcher.go @@ -1,10 +1,10 @@ package status_update import ( - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/service" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/service" ) func VmStatusFetcher() error { diff --git a/pkg/services/status_update/vm_status_listener.go b/pkg/services/status_update/vm_status_listener.go index bdaf73bb..ef304016 100644 --- a/pkg/services/status_update/vm_status_listener.go +++ b/pkg/services/status_update/vm_status_listener.go @@ -3,14 +3,14 @@ package status_update import ( "context" "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" - "go-deploy/service/v2/vms/k8s_service" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service/v2/vms/k8s_service" "go.mongodb.org/mongo-driver/bson" ) diff --git a/pkg/services/synchronize/fetch_gpu.go b/pkg/services/synchronize/fetch_gpu.go index 0cd1a324..e4f5ed27 100644 --- a/pkg/services/synchronize/fetch_gpu.go +++ b/pkg/services/synchronize/fetch_gpu.go @@ -2,15 +2,15 @@ package synchronize import ( "fmt" - "go-deploy/dto/v2/body" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/gpu_group_repo" - "go-deploy/pkg/db/resources/system_gpu_info_repo" - "go-deploy/pkg/log" - "go-deploy/service" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/gpu_group_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_gpu_info_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "strings" ) diff --git a/pkg/services/synchronize/service.go b/pkg/services/synchronize/service.go index 8bf31b82..c877874a 100644 --- a/pkg/services/synchronize/service.go +++ b/pkg/services/synchronize/service.go @@ -2,9 +2,9 @@ package synchronize import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) // Setup starts the synchronizers. diff --git a/pkg/services/synchronize/update_gpu_leases.go b/pkg/services/synchronize/update_gpu_leases.go index 7433244d..aadecb77 100644 --- a/pkg/services/synchronize/update_gpu_leases.go +++ b/pkg/services/synchronize/update_gpu_leases.go @@ -1,11 +1,11 @@ package synchronize import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/gpu_group_repo" - "go-deploy/pkg/db/resources/gpu_lease_repo" - "go-deploy/pkg/log" - "go-deploy/service" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/gpu_group_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/gpu_lease_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service" "sort" "time" ) diff --git a/pkg/services/system_state_poll/capacities_worker.go b/pkg/services/system_state_poll/capacities_worker.go index 8e6af4f5..11fc10f5 100644 --- a/pkg/services/system_state_poll/capacities_worker.go +++ b/pkg/services/system_state_poll/capacities_worker.go @@ -2,13 +2,13 @@ package system_state_poll import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/host_repo" - "go-deploy/pkg/db/resources/system_capacities_repo" - "go-deploy/pkg/subsystems/host_api" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_capacities_repo" + "github.com/kthcloud/go-deploy/pkg/subsystems/host_api" + "github.com/kthcloud/go-deploy/utils" "sync" "time" ) diff --git a/pkg/services/system_state_poll/common.go b/pkg/services/system_state_poll/common.go index b1df5678..60b60bb0 100644 --- a/pkg/services/system_state_poll/common.go +++ b/pkg/services/system_state_poll/common.go @@ -1,8 +1,8 @@ package system_state_poll import ( - "go-deploy/models/model" - wErrors "go-deploy/pkg/services/errors" + "github.com/kthcloud/go-deploy/models/model" + wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" "k8s.io/client-go/kubernetes" "log" "sync" diff --git a/pkg/services/system_state_poll/gpu_info_worker.go b/pkg/services/system_state_poll/gpu_info_worker.go index 63b73274..7d4d026d 100644 --- a/pkg/services/system_state_poll/gpu_info_worker.go +++ b/pkg/services/system_state_poll/gpu_info_worker.go @@ -2,13 +2,13 @@ package system_state_poll import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/host_repo" - "go-deploy/pkg/db/resources/system_gpu_info_repo" - wErrors "go-deploy/pkg/services/errors" - "go-deploy/pkg/subsystems/host_api" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_gpu_info_repo" + wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" + "github.com/kthcloud/go-deploy/pkg/subsystems/host_api" + "github.com/kthcloud/go-deploy/utils" "sync" "time" ) diff --git a/pkg/services/system_state_poll/service.go b/pkg/services/system_state_poll/service.go index b37325ff..8273fab8 100644 --- a/pkg/services/system_state_poll/service.go +++ b/pkg/services/system_state_poll/service.go @@ -2,9 +2,9 @@ package system_state_poll import ( "context" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/services" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/services" ) func Setup(ctx context.Context) { diff --git a/pkg/services/system_state_poll/stats_worker.go b/pkg/services/system_state_poll/stats_worker.go index b2a6ded5..7ec36604 100644 --- a/pkg/services/system_state_poll/stats_worker.go +++ b/pkg/services/system_state_poll/stats_worker.go @@ -2,12 +2,12 @@ package system_state_poll import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/system_stats_repo" - wErrors "go-deploy/pkg/services/errors" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_stats_repo" + wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/utils" "k8s.io/client-go/kubernetes" "log" "sync" diff --git a/pkg/services/system_state_poll/status_worker.go b/pkg/services/system_state_poll/status_worker.go index 8c20ff07..0016950e 100644 --- a/pkg/services/system_state_poll/status_worker.go +++ b/pkg/services/system_state_poll/status_worker.go @@ -2,13 +2,13 @@ package system_state_poll import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/host_repo" - "go-deploy/pkg/db/resources/system_status_repo" - wErrors "go-deploy/pkg/services/errors" - "go-deploy/pkg/subsystems/host_api" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_status_repo" + wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" + "github.com/kthcloud/go-deploy/pkg/subsystems/host_api" + "github.com/kthcloud/go-deploy/utils" "sync" "time" ) diff --git a/pkg/services/workers.go b/pkg/services/workers.go index 2996d450..5f05f9e8 100644 --- a/pkg/services/workers.go +++ b/pkg/services/workers.go @@ -4,10 +4,10 @@ import ( "context" "errors" "fmt" - "go-deploy/pkg/db/resources/host_repo" - "go-deploy/pkg/log" - wErrors "go-deploy/pkg/services/errors" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" + "github.com/kthcloud/go-deploy/pkg/log" + wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" + "github.com/kthcloud/go-deploy/utils" "strings" "time" ) diff --git a/pkg/subsystems/harbor/client.go b/pkg/subsystems/harbor/client.go index 6ab73818..6dd9d6bb 100644 --- a/pkg/subsystems/harbor/client.go +++ b/pkg/subsystems/harbor/client.go @@ -2,7 +2,7 @@ package harbor import ( "fmt" - "go-deploy/pkg/imp/harbor/harbor" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/harbor" ) // Client is a wrapper around the Harbor API client. diff --git a/pkg/subsystems/harbor/common.go b/pkg/subsystems/harbor/common.go index 344b2c6d..5e33098f 100644 --- a/pkg/subsystems/harbor/common.go +++ b/pkg/subsystems/harbor/common.go @@ -5,12 +5,12 @@ import ( "errors" "fmt" "github.com/go-openapi/runtime" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/repository" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/robot" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/robotv1" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhook" - "go-deploy/utils/requestutils" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/repository" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robot" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robotv1" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhook" + "github.com/kthcloud/go-deploy/utils/requestutils" "net/http" "strings" ) diff --git a/pkg/subsystems/harbor/models/project_create.go b/pkg/subsystems/harbor/models/project_create.go index 5885e993..97bc810f 100644 --- a/pkg/subsystems/harbor/models/project_create.go +++ b/pkg/subsystems/harbor/models/project_create.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" "strconv" ) diff --git a/pkg/subsystems/harbor/models/project_public.go b/pkg/subsystems/harbor/models/project_public.go index b6c1c604..915dd1bb 100644 --- a/pkg/subsystems/harbor/models/project_public.go +++ b/pkg/subsystems/harbor/models/project_public.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" "strconv" "time" ) diff --git a/pkg/subsystems/harbor/models/repository_public.go b/pkg/subsystems/harbor/models/repository_public.go index 72c322ac..8e887650 100644 --- a/pkg/subsystems/harbor/models/repository_public.go +++ b/pkg/subsystems/harbor/models/repository_public.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" "strings" "time" ) diff --git a/pkg/subsystems/harbor/models/robot_public.go b/pkg/subsystems/harbor/models/robot_public.go index 93f30f16..a95c3d0e 100644 --- a/pkg/subsystems/harbor/models/robot_public.go +++ b/pkg/subsystems/harbor/models/robot_public.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" "strings" "time" ) diff --git a/pkg/subsystems/harbor/models/webhook_public.go b/pkg/subsystems/harbor/models/webhook_public.go index 106647bf..8836d5de 100644 --- a/pkg/subsystems/harbor/models/webhook_public.go +++ b/pkg/subsystems/harbor/models/webhook_public.go @@ -3,7 +3,7 @@ package models import ( "encoding/base64" "fmt" - "go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" "strings" "time" ) diff --git a/pkg/subsystems/harbor/project.go b/pkg/subsystems/harbor/project.go index 2b880d3e..8fe078ec 100644 --- a/pkg/subsystems/harbor/project.go +++ b/pkg/subsystems/harbor/project.go @@ -3,9 +3,9 @@ package harbor import ( "context" "fmt" - projectModels "go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/harbor/models" + projectModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" "strconv" ) diff --git a/pkg/subsystems/harbor/repository.go b/pkg/subsystems/harbor/repository.go index b248691a..da610447 100644 --- a/pkg/subsystems/harbor/repository.go +++ b/pkg/subsystems/harbor/repository.go @@ -3,10 +3,10 @@ package harbor import ( "context" "fmt" - artifactModels "go-deploy/pkg/imp/harbor/sdk/v2.0/client/artifact" - repositoryModels "go-deploy/pkg/imp/harbor/sdk/v2.0/client/repository" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/harbor/models" + artifactModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/artifact" + repositoryModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/repository" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" ) // insertPlaceholder inserts a placeholder artifact into a repository. diff --git a/pkg/subsystems/harbor/robot.go b/pkg/subsystems/harbor/robot.go index 448a75d8..1572b1ee 100644 --- a/pkg/subsystems/harbor/robot.go +++ b/pkg/subsystems/harbor/robot.go @@ -4,11 +4,11 @@ import ( "context" "fmt" "github.com/go-openapi/strfmt" - robotModels "go-deploy/pkg/imp/harbor/sdk/v2.0/client/robot" - "go-deploy/pkg/imp/harbor/sdk/v2.0/client/robotv1" - harborModels "go-deploy/pkg/imp/harbor/sdk/v2.0/models" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/harbor/models" + robotModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robot" + "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robotv1" + harborModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" "time" "unicode" ) diff --git a/pkg/subsystems/harbor/webhook.go b/pkg/subsystems/harbor/webhook.go index 186eadc6..d7b31ac3 100644 --- a/pkg/subsystems/harbor/webhook.go +++ b/pkg/subsystems/harbor/webhook.go @@ -3,11 +3,11 @@ package harbor import ( "context" "fmt" - projectModels "go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" - webhookModels "go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhook" - harborModels "go-deploy/pkg/imp/harbor/sdk/v2.0/models" - "go-deploy/pkg/log" - models "go-deploy/pkg/subsystems/harbor/models" + projectModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" + webhookModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhook" + harborModels "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/models" + "github.com/kthcloud/go-deploy/pkg/log" + models "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" "strconv" ) diff --git a/pkg/subsystems/host_api/capacities.go b/pkg/subsystems/host_api/capacities.go index 695f6d62..5f950aea 100644 --- a/pkg/subsystems/host_api/capacities.go +++ b/pkg/subsystems/host_api/capacities.go @@ -2,7 +2,7 @@ package host_api import ( "fmt" - "go-deploy/utils/requestutils" + "github.com/kthcloud/go-deploy/utils/requestutils" ) func (c *Client) GetCapacities() (*Capacities, error) { diff --git a/pkg/subsystems/host_api/gpu_info.go b/pkg/subsystems/host_api/gpu_info.go index f7bbdafd..7ee7f1e7 100644 --- a/pkg/subsystems/host_api/gpu_info.go +++ b/pkg/subsystems/host_api/gpu_info.go @@ -2,7 +2,7 @@ package host_api import ( "fmt" - "go-deploy/utils/requestutils" + "github.com/kthcloud/go-deploy/utils/requestutils" ) func (c *Client) GetGpuInfo() ([]GpuInfo, error) { diff --git a/pkg/subsystems/host_api/node_info.go b/pkg/subsystems/host_api/node_info.go index 00cbe262..06ec4335 100644 --- a/pkg/subsystems/host_api/node_info.go +++ b/pkg/subsystems/host_api/node_info.go @@ -2,7 +2,7 @@ package host_api import ( "fmt" - "go-deploy/utils/requestutils" + "github.com/kthcloud/go-deploy/utils/requestutils" ) func (c *Client) GetNodeInfo() (*NodeInfo, error) { diff --git a/pkg/subsystems/host_api/status.go b/pkg/subsystems/host_api/status.go index 592d3a6c..b40774ae 100644 --- a/pkg/subsystems/host_api/status.go +++ b/pkg/subsystems/host_api/status.go @@ -2,7 +2,7 @@ package host_api import ( "fmt" - "go-deploy/utils/requestutils" + "github.com/kthcloud/go-deploy/utils/requestutils" ) func (c *Client) GetStatus() (*Status, error) { diff --git a/pkg/subsystems/k8s/client.go b/pkg/subsystems/k8s/client.go index 1b7ab767..3b45043e 100644 --- a/pkg/subsystems/k8s/client.go +++ b/pkg/subsystems/k8s/client.go @@ -2,7 +2,7 @@ package k8s import ( "fmt" - "go-deploy/pkg/imp/kubevirt/kubevirt" + "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt" "k8s.io/client-go/kubernetes" ) diff --git a/pkg/subsystems/k8s/deployment.go b/pkg/subsystems/k8s/deployment.go index 893bb031..4be4bd4a 100644 --- a/pkg/subsystems/k8s/deployment.go +++ b/pkg/subsystems/k8s/deployment.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "time" diff --git a/pkg/subsystems/k8s/hpa.go b/pkg/subsystems/k8s/hpa.go index ce8700ea..c54797fb 100644 --- a/pkg/subsystems/k8s/hpa.go +++ b/pkg/subsystems/k8s/hpa.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/ingress.go b/pkg/subsystems/k8s/ingress.go index f32b7b9e..432a0452 100644 --- a/pkg/subsystems/k8s/ingress.go +++ b/pkg/subsystems/k8s/ingress.go @@ -3,9 +3,9 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/errors" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/errors" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "strings" "time" diff --git a/pkg/subsystems/k8s/job.go b/pkg/subsystems/k8s/job.go index 2f52d48e..d7e9a222 100644 --- a/pkg/subsystems/k8s/job.go +++ b/pkg/subsystems/k8s/job.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/kubevirt.go b/pkg/subsystems/k8s/kubevirt.go index 9e1fd95e..f673c94a 100644 --- a/pkg/subsystems/k8s/kubevirt.go +++ b/pkg/subsystems/k8s/kubevirt.go @@ -2,7 +2,7 @@ package k8s import ( "context" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "kubevirt.io/api/core/v1" ) diff --git a/pkg/subsystems/k8s/logs.go b/pkg/subsystems/k8s/logs.go index 7f851586..937d6f00 100644 --- a/pkg/subsystems/k8s/logs.go +++ b/pkg/subsystems/k8s/logs.go @@ -4,10 +4,10 @@ import ( "bufio" "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/errors" "golang.org/x/exp/maps" "io" v1 "k8s.io/api/core/v1" diff --git a/pkg/subsystems/k8s/manifests.go b/pkg/subsystems/k8s/manifests.go index 81c9ea0d..8a8461fa 100644 --- a/pkg/subsystems/k8s/manifests.go +++ b/pkg/subsystems/k8s/manifests.go @@ -2,9 +2,9 @@ package k8s import ( "fmt" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/utils" appsv1 "k8s.io/api/apps/v1" autoscalingv2 "k8s.io/api/autoscaling/v2" v1 "k8s.io/api/batch/v1" diff --git a/pkg/subsystems/k8s/models/common.go b/pkg/subsystems/k8s/models/common.go index 428f0961..446be418 100644 --- a/pkg/subsystems/k8s/models/common.go +++ b/pkg/subsystems/k8s/models/common.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" v1 "k8s.io/api/core/v1" "time" ) diff --git a/pkg/subsystems/k8s/models/ingress_public.go b/pkg/subsystems/k8s/models/ingress_public.go index 7b022d49..2fd09703 100644 --- a/pkg/subsystems/k8s/models/ingress_public.go +++ b/pkg/subsystems/k8s/models/ingress_public.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" v1 "k8s.io/api/networking/v1" "time" ) diff --git a/pkg/subsystems/k8s/models/vm.go b/pkg/subsystems/k8s/models/vm.go index 536464c0..d5df5dee 100644 --- a/pkg/subsystems/k8s/models/vm.go +++ b/pkg/subsystems/k8s/models/vm.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" kubevirtv1 "kubevirt.io/api/core/v1" "time" ) diff --git a/pkg/subsystems/k8s/models/vm_snapshot.go b/pkg/subsystems/k8s/models/vm_snapshot.go index 69d08abc..3535c210 100644 --- a/pkg/subsystems/k8s/models/vm_snapshot.go +++ b/pkg/subsystems/k8s/models/vm_snapshot.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" "kubevirt.io/api/snapshot/v1alpha1" "time" ) diff --git a/pkg/subsystems/k8s/models/vm_status.go b/pkg/subsystems/k8s/models/vm_status.go index 5574959f..f2ae2e6d 100644 --- a/pkg/subsystems/k8s/models/vm_status.go +++ b/pkg/subsystems/k8s/models/vm_status.go @@ -1,7 +1,7 @@ package models import ( - "go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" kubevirtv1 "kubevirt.io/api/core/v1" ) diff --git a/pkg/subsystems/k8s/namespace.go b/pkg/subsystems/k8s/namespace.go index 56f4afa9..ef33a60e 100644 --- a/pkg/subsystems/k8s/namespace.go +++ b/pkg/subsystems/k8s/namespace.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "strings" "time" diff --git a/pkg/subsystems/k8s/network_policy.go b/pkg/subsystems/k8s/network_policy.go index 4e9200fb..abd878a8 100644 --- a/pkg/subsystems/k8s/network_policy.go +++ b/pkg/subsystems/k8s/network_policy.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/node.go b/pkg/subsystems/k8s/node.go index 028a8442..917f4c57 100644 --- a/pkg/subsystems/k8s/node.go +++ b/pkg/subsystems/k8s/node.go @@ -3,7 +3,7 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/subsystems/k8s/pod.go b/pkg/subsystems/k8s/pod.go index d7eccf0b..81ea91e9 100644 --- a/pkg/subsystems/k8s/pod.go +++ b/pkg/subsystems/k8s/pod.go @@ -2,8 +2,8 @@ package k8s import ( "context" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/informers" diff --git a/pkg/subsystems/k8s/pv.go b/pkg/subsystems/k8s/pv.go index 6a8f26d1..1a5c4a96 100644 --- a/pkg/subsystems/k8s/pv.go +++ b/pkg/subsystems/k8s/pv.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/pvc.go b/pkg/subsystems/k8s/pvc.go index a09d8925..789ff197 100644 --- a/pkg/subsystems/k8s/pvc.go +++ b/pkg/subsystems/k8s/pvc.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/secret.go b/pkg/subsystems/k8s/secret.go index 2f6ecd23..dae82ed2 100644 --- a/pkg/subsystems/k8s/secret.go +++ b/pkg/subsystems/k8s/secret.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/service.go b/pkg/subsystems/k8s/service.go index ee13d73e..5877f3a0 100644 --- a/pkg/subsystems/k8s/service.go +++ b/pkg/subsystems/k8s/service.go @@ -3,8 +3,8 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/status.go b/pkg/subsystems/k8s/status.go index 6219cd74..df1c4791 100644 --- a/pkg/subsystems/k8s/status.go +++ b/pkg/subsystems/k8s/status.go @@ -3,10 +3,10 @@ package k8s import ( "context" "fmt" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/pkg/subsystems/k8s/opts" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/opts" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/subsystems/k8s/vm.go b/pkg/subsystems/k8s/vm.go index 70d2bf78..a6cc6fa8 100644 --- a/pkg/subsystems/k8s/vm.go +++ b/pkg/subsystems/k8s/vm.go @@ -4,10 +4,10 @@ import ( "context" "fmt" "github.com/google/uuid" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/k8s/vm_snapshot.go b/pkg/subsystems/k8s/vm_snapshot.go index 9a02bf88..f394a755 100644 --- a/pkg/subsystems/k8s/vm_snapshot.go +++ b/pkg/subsystems/k8s/vm_snapshot.go @@ -4,8 +4,8 @@ import ( "context" "fmt" "github.com/google/uuid" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time" ) diff --git a/pkg/subsystems/rancher/cluster.go b/pkg/subsystems/rancher/cluster.go index bfce1d49..352c9643 100644 --- a/pkg/subsystems/rancher/cluster.go +++ b/pkg/subsystems/rancher/cluster.go @@ -3,7 +3,7 @@ package rancher import ( "encoding/json" "fmt" - "go-deploy/pkg/subsystems/rancher/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/rancher/models" "io" "net/http" "strings" diff --git a/pkg/sys/auth.go b/pkg/sys/auth.go index 3c3137cc..b408f74c 100644 --- a/pkg/sys/auth.go +++ b/pkg/sys/auth.go @@ -3,8 +3,8 @@ package sys import ( "encoding/json" "fmt" - "go-deploy/pkg/auth" - "go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/auth" + "github.com/kthcloud/go-deploy/pkg/config" ) // HasApiKey checks if the request has an api key. diff --git a/pkg/sys/client_context.go b/pkg/sys/client_context.go index 6e26ae28..da69f756 100644 --- a/pkg/sys/client_context.go +++ b/pkg/sys/client_context.go @@ -2,10 +2,10 @@ package sys import ( "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/app/status_codes" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/utils" "net/http" ) diff --git a/routers/api/v2/api_key.go b/routers/api/v2/api_key.go index d015f1a2..529bf74d 100644 --- a/routers/api/v2/api_key.go +++ b/routers/api/v2/api_key.go @@ -3,11 +3,11 @@ package v2 import ( "errors" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/uri" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" ) // CreateApiKey diff --git a/routers/api/v2/deployment.go b/routers/api/v2/deployment.go index c375b470..d0be0c31 100644 --- a/routers/api/v2/deployment.go +++ b/routers/api/v2/deployment.go @@ -4,19 +4,19 @@ import ( "errors" "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/deployments/opts" - teamOpts "go-deploy/service/v2/teams/opts" - v12 "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + teamOpts "github.com/kthcloud/go-deploy/service/v2/teams/opts" + v12 "github.com/kthcloud/go-deploy/service/v2/utils" "strconv" "strings" ) diff --git a/routers/api/v2/deployment_ci_config.go b/routers/api/v2/deployment_ci_config.go index efc625fb..5ed6cb8c 100644 --- a/routers/api/v2/deployment_ci_config.go +++ b/routers/api/v2/deployment_ci_config.go @@ -3,10 +3,10 @@ package v2 import ( "errors" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/uri" - "go-deploy/pkg/sys" - "go-deploy/service" - dErrors "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + dErrors "github.com/kthcloud/go-deploy/service/errors" "net/http" ) diff --git a/routers/api/v2/deployment_command.go b/routers/api/v2/deployment_command.go index 8976da96..99cd65b5 100644 --- a/routers/api/v2/deployment_command.go +++ b/routers/api/v2/deployment_command.go @@ -2,11 +2,11 @@ package v2 import ( "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/uri" - "go-deploy/pkg/sys" - "go-deploy/service" - "go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" ) // DoDeploymentCommand diff --git a/routers/api/v2/deployment_hook.go b/routers/api/v2/deployment_hook.go index 1e72b3ee..724775c7 100644 --- a/routers/api/v2/deployment_hook.go +++ b/routers/api/v2/deployment_hook.go @@ -5,12 +5,12 @@ import ( "errors" "fmt" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" "strings" "time" ) diff --git a/routers/api/v2/deployment_logs.go b/routers/api/v2/deployment_logs.go index 8cb0473b..512e3aee 100644 --- a/routers/api/v2/deployment_logs.go +++ b/routers/api/v2/deployment_logs.go @@ -4,12 +4,12 @@ import ( "context" "errors" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/uri" - "go-deploy/pkg/sys" - "go-deploy/service" - errors2 "go-deploy/service/errors" - "go-deploy/service/v2/deployments" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + errors2 "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/deployments" "io" "time" ) diff --git a/routers/api/v2/discover.go b/routers/api/v2/discover.go index 9ad29ae9..8da63602 100644 --- a/routers/api/v2/discover.go +++ b/routers/api/v2/discover.go @@ -2,8 +2,8 @@ package v2 import ( "github.com/gin-gonic/gin" - "go-deploy/pkg/sys" - "go-deploy/service" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" ) // Discover diff --git a/routers/api/v2/gpu_group.go b/routers/api/v2/gpu_group.go index 10affab4..290bd911 100644 --- a/routers/api/v2/gpu_group.go +++ b/routers/api/v2/gpu_group.go @@ -2,13 +2,13 @@ package v2 import ( "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/pkg/sys" - "go-deploy/service" - "go-deploy/service/v2/utils" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" ) // GetGpuGroup diff --git a/routers/api/v2/gpu_lease.go b/routers/api/v2/gpu_lease.go index efe151b8..98dbb932 100644 --- a/routers/api/v2/gpu_lease.go +++ b/routers/api/v2/gpu_lease.go @@ -4,16 +4,16 @@ import ( "errors" "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/utils" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" ) // GetGpuLease diff --git a/routers/api/v2/hosts.go b/routers/api/v2/hosts.go index 2ce2afa5..1b757042 100644 --- a/routers/api/v2/hosts.go +++ b/routers/api/v2/hosts.go @@ -3,9 +3,9 @@ package v2 import ( "fmt" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/pkg/sys" - "go-deploy/service" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" ) // ListHosts diff --git a/routers/api/v2/job.go b/routers/api/v2/job.go index 734d8d83..ca5574ab 100644 --- a/routers/api/v2/job.go +++ b/routers/api/v2/job.go @@ -3,16 +3,16 @@ package v2 import ( "errors" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/models/model" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/jobs/opts" - v12 "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/jobs/opts" + v12 "github.com/kthcloud/go-deploy/service/v2/utils" ) // GetJob diff --git a/routers/api/v2/middleware/access_gpu_routes.go b/routers/api/v2/middleware/access_gpu_routes.go index bd097443..0457d51f 100644 --- a/routers/api/v2/middleware/access_gpu_routes.go +++ b/routers/api/v2/middleware/access_gpu_routes.go @@ -2,9 +2,9 @@ package middleware import ( "github.com/gin-gonic/gin" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/sys" - v2 "go-deploy/routers/api/v2" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/sys" + v2 "github.com/kthcloud/go-deploy/routers/api/v2" "net/http" ) diff --git a/routers/api/v2/middleware/create_storage_manager.go b/routers/api/v2/middleware/create_storage_manager.go index 4efa3a41..fef8273d 100644 --- a/routers/api/v2/middleware/create_storage_manager.go +++ b/routers/api/v2/middleware/create_storage_manager.go @@ -4,13 +4,13 @@ import ( "fmt" "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/sys" - v2 "go-deploy/routers/api/v2" - "go-deploy/service" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/sys" + v2 "github.com/kthcloud/go-deploy/routers/api/v2" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/utils" ) // CreateSM is a middleware that creates a storage manager for the user if it does not exist. diff --git a/routers/api/v2/middleware/synchronize_user.go b/routers/api/v2/middleware/synchronize_user.go index f589bfda..b018ff0b 100644 --- a/routers/api/v2/middleware/synchronize_user.go +++ b/routers/api/v2/middleware/synchronize_user.go @@ -3,11 +3,11 @@ package middleware import ( "fmt" "github.com/gin-gonic/gin" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/sys" - v2 "go-deploy/routers/api/v2" - "go-deploy/service" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/sys" + v2 "github.com/kthcloud/go-deploy/routers/api/v2" + "github.com/kthcloud/go-deploy/service" ) // SetupAuthUser is a middleware that sets up the authenticated user in the context. diff --git a/routers/api/v2/notification.go b/routers/api/v2/notification.go index 6331c89e..c0015654 100644 --- a/routers/api/v2/notification.go +++ b/routers/api/v2/notification.go @@ -3,14 +3,14 @@ package v2 import ( "errors" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/notifications/opts" - v12 "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/notifications/opts" + v12 "github.com/kthcloud/go-deploy/service/v2/utils" "net/http" ) diff --git a/routers/api/v2/register.go b/routers/api/v2/register.go index e70d1e32..7b6352fd 100644 --- a/routers/api/v2/register.go +++ b/routers/api/v2/register.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" - "go-deploy/dto/v2/body" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" ) // Register diff --git a/routers/api/v2/resource_migration.go b/routers/api/v2/resource_migration.go index c68d5da9..d5f42882 100644 --- a/routers/api/v2/resource_migration.go +++ b/routers/api/v2/resource_migration.go @@ -4,13 +4,13 @@ import ( "errors" "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/resource_migrations/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/resource_migrations/opts" "net/http" ) diff --git a/routers/api/v2/sm.go b/routers/api/v2/sm.go index 8a68e9ae..6ae410ac 100644 --- a/routers/api/v2/sm.go +++ b/routers/api/v2/sm.go @@ -3,17 +3,17 @@ package v2 import ( "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/app/status_codes" - "go-deploy/pkg/config" - "go-deploy/pkg/sys" - "go-deploy/service" - "go-deploy/service/v2/sms/opts" - v12 "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/service/v2/sms/opts" + v12 "github.com/kthcloud/go-deploy/service/v2/utils" "net/http" "strconv" "strings" diff --git a/routers/api/v2/snapshot.go b/routers/api/v2/snapshot.go index eaf06f4c..cc685add 100644 --- a/routers/api/v2/snapshot.go +++ b/routers/api/v2/snapshot.go @@ -4,16 +4,16 @@ import ( "errors" "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/utils" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" ) // GetSnapshot diff --git a/routers/api/v2/system.go b/routers/api/v2/system.go index afe18433..ed896dbc 100644 --- a/routers/api/v2/system.go +++ b/routers/api/v2/system.go @@ -2,9 +2,9 @@ package v2 import ( "github.com/gin-gonic/gin" - "go-deploy/dto/v2/query" - "go-deploy/pkg/sys" - "go-deploy/service" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" "net/http" ) diff --git a/routers/api/v2/team.go b/routers/api/v2/team.go index 7e5ead6e..de28bbb6 100644 --- a/routers/api/v2/team.go +++ b/routers/api/v2/team.go @@ -6,18 +6,18 @@ import ( "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/models/model" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - deploymentOpts "go-deploy/service/v2/deployments/opts" - "go-deploy/service/v2/teams/opts" - v12 "go-deploy/service/v2/utils" - vmOpts "go-deploy/service/v2/vms/opts" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + deploymentOpts "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/service/v2/teams/opts" + v12 "github.com/kthcloud/go-deploy/service/v2/utils" + vmOpts "github.com/kthcloud/go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/utils" "net/http" "time" ) diff --git a/routers/api/v2/user.go b/routers/api/v2/user.go index 214492f2..0f233241 100644 --- a/routers/api/v2/user.go +++ b/routers/api/v2/user.go @@ -3,16 +3,16 @@ package v2 import ( "errors" "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - "go-deploy/service/v2/users/opts" - sUtils "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/users/opts" + sUtils "github.com/kthcloud/go-deploy/service/v2/utils" ) // GetUser diff --git a/routers/api/v2/utils.go b/routers/api/v2/utils.go index 23d36651..c1c82806 100644 --- a/routers/api/v2/utils.go +++ b/routers/api/v2/utils.go @@ -5,9 +5,9 @@ import ( "errors" "fmt" "github.com/go-playground/validator/v10" - "go-deploy/dto/v2/body" - "go-deploy/pkg/sys" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service/core" "reflect" ) diff --git a/routers/api/v2/vm.go b/routers/api/v2/vm.go index 38169fd9..f1326a58 100644 --- a/routers/api/v2/vm.go +++ b/routers/api/v2/vm.go @@ -4,19 +4,19 @@ import ( "errors" "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/dto/v2/uri" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/sys" - "go-deploy/service" - sErrors "go-deploy/service/errors" - teamOpts "go-deploy/service/v2/teams/opts" - v2Utils "go-deploy/service/v2/utils" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/dto/v2/uri" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + sErrors "github.com/kthcloud/go-deploy/service/errors" + teamOpts "github.com/kthcloud/go-deploy/service/v2/teams/opts" + v2Utils "github.com/kthcloud/go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" "strconv" "strings" ) diff --git a/routers/api/v2/vm_action.go b/routers/api/v2/vm_action.go index 34506f40..01d8f54c 100644 --- a/routers/api/v2/vm_action.go +++ b/routers/api/v2/vm_action.go @@ -3,13 +3,13 @@ package v2 import ( "github.com/gin-gonic/gin" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/sys" - "go-deploy/service" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" ) // CreateVmAction diff --git a/routers/api/v2/worker_status.go b/routers/api/v2/worker_status.go index 40168113..25fac8df 100644 --- a/routers/api/v2/worker_status.go +++ b/routers/api/v2/worker_status.go @@ -2,11 +2,11 @@ package v2 import ( "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/pkg/sys" - "go-deploy/service" - "go-deploy/service/v2/system/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" + "github.com/kthcloud/go-deploy/service/v2/system/opts" ) // ListWorkerStatus diff --git a/routers/api/v2/zone.go b/routers/api/v2/zone.go index 19042e73..491434d3 100644 --- a/routers/api/v2/zone.go +++ b/routers/api/v2/zone.go @@ -2,10 +2,10 @@ package v2 import ( "github.com/gin-gonic/gin" - "go-deploy/dto/v2/body" - "go-deploy/dto/v2/query" - "go-deploy/pkg/sys" - "go-deploy/service" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/dto/v2/query" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/service" ) // ListZones diff --git a/routers/api/validators/validators.go b/routers/api/validators/validators.go index 04aafc3f..4e798bb5 100644 --- a/routers/api/validators/validators.go +++ b/routers/api/validators/validators.go @@ -2,8 +2,8 @@ package validators import ( "github.com/go-playground/validator/v10" - bodyV2 "go-deploy/dto/v2/body" - "go-deploy/pkg/config" + bodyV2 "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/config" "golang.org/x/crypto/ssh" "golang.org/x/net/idna" "regexp" diff --git a/routers/router.go b/routers/router.go index 193d4c80..86265649 100644 --- a/routers/router.go +++ b/routers/router.go @@ -8,16 +8,16 @@ import ( "github.com/penglongli/gin-metrics/ginmetrics" swaggerfiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" - docsV2 "go-deploy/docs/api/v2" - "go-deploy/models/mode" - "go-deploy/pkg/auth" - "go-deploy/pkg/config" - "go-deploy/pkg/log" - "go-deploy/pkg/metrics" - "go-deploy/pkg/sys" - "go-deploy/routers/api/v2/middleware" - "go-deploy/routers/api/validators" - "go-deploy/routers/routes" + docsV2 "github.com/kthcloud/go-deploy/docs/api/v2" + "github.com/kthcloud/go-deploy/models/mode" + "github.com/kthcloud/go-deploy/pkg/auth" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/metrics" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/routers/api/v2/middleware" + "github.com/kthcloud/go-deploy/routers/api/validators" + "github.com/kthcloud/go-deploy/routers/routes" "net/http" "net/url" "reflect" diff --git a/routers/routes/deployment.go b/routers/routes/deployment.go index 76132229..3f2685b9 100644 --- a/routers/routes/deployment.go +++ b/routers/routes/deployment.go @@ -2,8 +2,8 @@ package routes import ( "github.com/gin-gonic/gin" - v2 "go-deploy/routers/api/v2" - "go-deploy/routers/api/v2/middleware" + v2 "github.com/kthcloud/go-deploy/routers/api/v2" + "github.com/kthcloud/go-deploy/routers/api/v2/middleware" ) const ( diff --git a/routers/routes/discover.go b/routers/routes/discover.go index 3db1cbb2..0a38164d 100644 --- a/routers/routes/discover.go +++ b/routers/routes/discover.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( DiscoverPath = "/v2/discover" diff --git a/routers/routes/gpu_group.go b/routers/routes/gpu_group.go index 9d7f3db6..d0ec02a7 100644 --- a/routers/routes/gpu_group.go +++ b/routers/routes/gpu_group.go @@ -1,6 +1,6 @@ package routes -import "go-deploy/routers/api/v2" +import "github.com/kthcloud/go-deploy/routers/api/v2" const ( GpuGroupsPath = "/v2/gpuGroups" diff --git a/routers/routes/gpu_lease.go b/routers/routes/gpu_lease.go index 259e960c..1a5b4e01 100644 --- a/routers/routes/gpu_lease.go +++ b/routers/routes/gpu_lease.go @@ -1,6 +1,6 @@ package routes -import "go-deploy/routers/api/v2" +import "github.com/kthcloud/go-deploy/routers/api/v2" const ( GpuLeasesPath = "/v2/gpuLeases" diff --git a/routers/routes/host.go b/routers/routes/host.go index 97d0e20c..1809642a 100644 --- a/routers/routes/host.go +++ b/routers/routes/host.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( HostsPath = "/v2/hosts" diff --git a/routers/routes/job.go b/routers/routes/job.go index a8833477..2de47917 100644 --- a/routers/routes/job.go +++ b/routers/routes/job.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( JobsPath = "/v2/jobs" diff --git a/routers/routes/metrics.go b/routers/routes/metrics.go index 33f9dde0..1d242bf7 100644 --- a/routers/routes/metrics.go +++ b/routers/routes/metrics.go @@ -3,8 +3,8 @@ package routes import ( "fmt" "github.com/gin-gonic/gin" - "go-deploy/pkg/config" - "go-deploy/pkg/metrics" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/metrics" "net/http" "net/http/httputil" ) diff --git a/routers/routes/notification.go b/routers/routes/notification.go index f6a8272e..ae6e88fd 100644 --- a/routers/routes/notification.go +++ b/routers/routes/notification.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( NotificationsPath = "/v2/notifications" diff --git a/routers/routes/register.go b/routers/routes/register.go index d6b29c1c..04285c06 100644 --- a/routers/routes/register.go +++ b/routers/routes/register.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( RegisterPath = "/v2/register" diff --git a/routers/routes/resource_migration.go b/routers/routes/resource_migration.go index 9246c94a..c3281954 100644 --- a/routers/routes/resource_migration.go +++ b/routers/routes/resource_migration.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( ResourceMigrationsPath = "/v2/resourceMigrations" diff --git a/routers/routes/sm.go b/routers/routes/sm.go index a9316290..4fbe60a6 100644 --- a/routers/routes/sm.go +++ b/routers/routes/sm.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( SMsPath = "/v2/storageManagers" diff --git a/routers/routes/snapshot.go b/routers/routes/snapshot.go index cdb63b2f..12598dc3 100644 --- a/routers/routes/snapshot.go +++ b/routers/routes/snapshot.go @@ -1,6 +1,6 @@ package routes -import "go-deploy/routers/api/v2" +import "github.com/kthcloud/go-deploy/routers/api/v2" const ( SnapshotsPath = "/v2/snapshots" diff --git a/routers/routes/system.go b/routers/routes/system.go index 3a44e159..27b256cc 100644 --- a/routers/routes/system.go +++ b/routers/routes/system.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( SystemCapacitiesPath = "/v2/systemCapacities" diff --git a/routers/routes/team.go b/routers/routes/team.go index 766aceee..1c84e3e7 100644 --- a/routers/routes/team.go +++ b/routers/routes/team.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( TeamsPath = "/v2/teams" diff --git a/routers/routes/user.go b/routers/routes/user.go index 6c3f547d..c639b03e 100644 --- a/routers/routes/user.go +++ b/routers/routes/user.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( UsersPath = "/v2/users" diff --git a/routers/routes/vm.go b/routers/routes/vm.go index 3000a6e5..e5f21391 100644 --- a/routers/routes/vm.go +++ b/routers/routes/vm.go @@ -1,7 +1,7 @@ package routes import ( - v2 "go-deploy/routers/api/v2" + v2 "github.com/kthcloud/go-deploy/routers/api/v2" ) const ( diff --git a/routers/routes/vm_action.go b/routers/routes/vm_action.go index 6b96fda9..0190cb77 100644 --- a/routers/routes/vm_action.go +++ b/routers/routes/vm_action.go @@ -1,6 +1,6 @@ package routes -import "go-deploy/routers/api/v2" +import "github.com/kthcloud/go-deploy/routers/api/v2" const ( VmActionsPath = "/v2/vmActions" diff --git a/routers/routes/zone.go b/routers/routes/zone.go index bab10999..53df19cb 100644 --- a/routers/routes/zone.go +++ b/routers/routes/zone.go @@ -1,6 +1,6 @@ package routes -import v2 "go-deploy/routers/api/v2" +import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( ZonesPath = "/v2/zones" diff --git a/service/client.go b/service/client.go index 43d775c5..0824fc6b 100644 --- a/service/client.go +++ b/service/client.go @@ -1,9 +1,9 @@ package service import ( - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2" ) func V2(authInfo ...*core.AuthInfo) clients.V2 { diff --git a/service/clients/v2.go b/service/clients/v2.go index 4b683342..a5e3f3ae 100644 --- a/service/clients/v2.go +++ b/service/clients/v2.go @@ -1,8 +1,8 @@ package clients import ( - "go-deploy/service/core" - apiV2 "go-deploy/service/v2/api" + "github.com/kthcloud/go-deploy/service/core" + apiV2 "github.com/kthcloud/go-deploy/service/v2/api" ) type V2 interface { diff --git a/service/core/auth_info.go b/service/core/auth_info.go index 9b7d6193..a24473ad 100644 --- a/service/core/auth_info.go +++ b/service/core/auth_info.go @@ -1,8 +1,8 @@ package core import ( - "go-deploy/models/model" - "go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" ) // AuthInfo is used to pass auth info to services diff --git a/service/core/cache.go b/service/core/cache.go index 88292f2f..8c8992c6 100644 --- a/service/core/cache.go +++ b/service/core/cache.go @@ -1,6 +1,6 @@ package core -import "go-deploy/models/model" +import "github.com/kthcloud/go-deploy/models/model" // Cache is a cache for all resources fetched inside the service. // This is used to avoid fetching the same model multiple times. diff --git a/service/generators/harbor_generator.go b/service/generators/harbor_generator.go index 259713f1..63eb5e0c 100644 --- a/service/generators/harbor_generator.go +++ b/service/generators/harbor_generator.go @@ -1,7 +1,7 @@ package generators import ( - "go-deploy/pkg/subsystems/harbor/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" ) // HarborGenerator is a generator for Harbor resources diff --git a/service/generators/k8s_generator.go b/service/generators/k8s_generator.go index 72e69290..ef8ff4da 100644 --- a/service/generators/k8s_generator.go +++ b/service/generators/k8s_generator.go @@ -1,7 +1,7 @@ package generators import ( - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" ) // K8sGenerator is a generator for K8s resources diff --git a/service/resources/resource_creator.go b/service/resources/resource_creator.go index 1659cfa3..9d31ec95 100644 --- a/service/resources/resource_creator.go +++ b/service/resources/resource_creator.go @@ -1,8 +1,8 @@ package resources import ( - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" ) // SsCreatorType is a type that can be used to create a single subsystem model diff --git a/service/resources/resource_deleter.go b/service/resources/resource_deleter.go index b179f7a8..148ee2ca 100644 --- a/service/resources/resource_deleter.go +++ b/service/resources/resource_deleter.go @@ -1,7 +1,7 @@ package resources import ( - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/log" ) // SsDeleterType is a type that can be used to delete a single subsystem model diff --git a/service/resources/resource_placeholder_creator.go b/service/resources/resource_placeholder_creator.go index e1f20a99..993fa904 100644 --- a/service/resources/resource_placeholder_creator.go +++ b/service/resources/resource_placeholder_creator.go @@ -1,7 +1,7 @@ package resources import ( - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/log" ) // SsPlaceholderCreatorType is a type that can be used to create a single subsystem placeholder model. diff --git a/service/resources/resource_repairer.go b/service/resources/resource_repairer.go index a61f7a33..2a08189b 100644 --- a/service/resources/resource_repairer.go +++ b/service/resources/resource_repairer.go @@ -1,9 +1,9 @@ package resources import ( - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" - "go-deploy/service/utils" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/service/utils" ) // SsRepairerType is a type that can be used to repair a single subsystem model diff --git a/service/resources/resource_updater.go b/service/resources/resource_updater.go index c79fd5c3..f53d1f9b 100644 --- a/service/resources/resource_updater.go +++ b/service/resources/resource_updater.go @@ -1,8 +1,8 @@ package resources import ( - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" ) // SsUpdaterType is a type that can be used to update a single subsystem model diff --git a/service/utils/utils.go b/service/utils/utils.go index 9f96c79d..506b238f 100644 --- a/service/utils/utils.go +++ b/service/utils/utils.go @@ -3,8 +3,8 @@ package utils import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" "reflect" "time" ) diff --git a/service/v2/api/api_client.go b/service/v2/api/api_client.go index 01c6a0ba..f3ee9d94 100644 --- a/service/v2/api/api_client.go +++ b/service/v2/api/api_client.go @@ -2,22 +2,22 @@ package api import ( "context" - "go-deploy/dto/v2/body" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/service/v2/deployments/harbor_service" - deploymentK8sService "go-deploy/service/v2/deployments/k8s_service" - dOpts "go-deploy/service/v2/deployments/opts" - jobOpts "go-deploy/service/v2/jobs/opts" - nOpts "go-deploy/service/v2/notifications/opts" - resourceMigrationOpts "go-deploy/service/v2/resource_migrations/opts" - smK8sService "go-deploy/service/v2/sms/k8s_service" - smOpts "go-deploy/service/v2/sms/opts" - systemOpts "go-deploy/service/v2/system/opts" - teamOpts "go-deploy/service/v2/teams/opts" - userOpts "go-deploy/service/v2/users/opts" - vmK8sService "go-deploy/service/v2/vms/k8s_service" - vmOpts "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/service/v2/deployments/harbor_service" + deploymentK8sService "github.com/kthcloud/go-deploy/service/v2/deployments/k8s_service" + dOpts "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + jobOpts "github.com/kthcloud/go-deploy/service/v2/jobs/opts" + nOpts "github.com/kthcloud/go-deploy/service/v2/notifications/opts" + resourceMigrationOpts "github.com/kthcloud/go-deploy/service/v2/resource_migrations/opts" + smK8sService "github.com/kthcloud/go-deploy/service/v2/sms/k8s_service" + smOpts "github.com/kthcloud/go-deploy/service/v2/sms/opts" + systemOpts "github.com/kthcloud/go-deploy/service/v2/system/opts" + teamOpts "github.com/kthcloud/go-deploy/service/v2/teams/opts" + userOpts "github.com/kthcloud/go-deploy/service/v2/users/opts" + vmK8sService "github.com/kthcloud/go-deploy/service/v2/vms/k8s_service" + vmOpts "github.com/kthcloud/go-deploy/service/v2/vms/opts" "time" ) diff --git a/service/v2/client.go b/service/v2/client.go index 730b7b43..03053fa8 100644 --- a/service/v2/client.go +++ b/service/v2/client.go @@ -1,19 +1,19 @@ package v2 import ( - "go-deploy/service/core" - "go-deploy/service/v2/api" - "go-deploy/service/v2/deployments" - "go-deploy/service/v2/discovery" - "go-deploy/service/v2/events" - "go-deploy/service/v2/jobs" - "go-deploy/service/v2/notifications" - "go-deploy/service/v2/resource_migrations" - "go-deploy/service/v2/sms" - "go-deploy/service/v2/system" - "go-deploy/service/v2/teams" - "go-deploy/service/v2/users" - "go-deploy/service/v2/vms" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/api" + "github.com/kthcloud/go-deploy/service/v2/deployments" + "github.com/kthcloud/go-deploy/service/v2/discovery" + "github.com/kthcloud/go-deploy/service/v2/events" + "github.com/kthcloud/go-deploy/service/v2/jobs" + "github.com/kthcloud/go-deploy/service/v2/notifications" + "github.com/kthcloud/go-deploy/service/v2/resource_migrations" + "github.com/kthcloud/go-deploy/service/v2/sms" + "github.com/kthcloud/go-deploy/service/v2/system" + "github.com/kthcloud/go-deploy/service/v2/teams" + "github.com/kthcloud/go-deploy/service/v2/users" + "github.com/kthcloud/go-deploy/service/v2/vms" ) type Client struct { diff --git a/service/v2/deployments/api_client.go b/service/v2/deployments/api_client.go index b2529fdc..9be8b640 100644 --- a/service/v2/deployments/api_client.go +++ b/service/v2/deployments/api_client.go @@ -1,11 +1,11 @@ package deployments import ( - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2/deployments/client" - "go-deploy/service/v2/deployments/harbor_service" - "go-deploy/service/v2/deployments/k8s_service" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/deployments/client" + "github.com/kthcloud/go-deploy/service/v2/deployments/harbor_service" + "github.com/kthcloud/go-deploy/service/v2/deployments/k8s_service" ) // Client is the client for the Deployment service. diff --git a/service/v2/deployments/ci_config_service.go b/service/v2/deployments/ci_config_service.go index e03a043b..88df13e0 100644 --- a/service/v2/deployments/ci_config_service.go +++ b/service/v2/deployments/ci_config_service.go @@ -2,12 +2,12 @@ package deployments import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/service/errors" - "go-deploy/service/v2/deployments/opts" - "go-deploy/utils/subsystemutils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/utils/subsystemutils" "gopkg.in/yaml.v3" "strings" ) diff --git a/service/v2/deployments/client/client.go b/service/v2/deployments/client/client.go index 24eec2a9..c4708878 100644 --- a/service/v2/deployments/client/client.go +++ b/service/v2/deployments/client/client.go @@ -2,9 +2,9 @@ package client import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/service/core" ) // BaseClient is the base client for all the subsystems client for deployments. diff --git a/service/v2/deployments/deployment_service.go b/service/v2/deployments/deployment_service.go index 28550af2..2b13a6ef 100644 --- a/service/v2/deployments/deployment_service.go +++ b/service/v2/deployments/deployment_service.go @@ -3,21 +3,21 @@ package deployments import ( "errors" "fmt" - "go-deploy/dto/v2/body" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/deployment_repo" - rErrors "go-deploy/pkg/db/resources/errors" - "go-deploy/pkg/db/resources/notification_repo" - "go-deploy/pkg/db/resources/resource_migration_repo" - "go-deploy/pkg/db/resources/team_repo" - "go-deploy/pkg/log" - sErrors "go-deploy/service/errors" - sUtils "go-deploy/service/utils" - "go-deploy/service/v2/deployments/opts" - "go-deploy/utils" - "go-deploy/utils/subsystemutils" + "github.com/kthcloud/go-deploy/dto/v2/body" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + rErrors "github.com/kthcloud/go-deploy/pkg/db/resources/errors" + "github.com/kthcloud/go-deploy/pkg/db/resources/notification_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/resource_migration_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/team_repo" + "github.com/kthcloud/go-deploy/pkg/log" + sErrors "github.com/kthcloud/go-deploy/service/errors" + sUtils "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/utils" + "github.com/kthcloud/go-deploy/utils/subsystemutils" "go.mongodb.org/mongo-driver/bson" "sort" "time" diff --git a/service/v2/deployments/harbor_service/client.go b/service/v2/deployments/harbor_service/client.go index a549a48f..717d0c92 100644 --- a/service/v2/deployments/harbor_service/client.go +++ b/service/v2/deployments/harbor_service/client.go @@ -1,17 +1,17 @@ package harbor_service import ( - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems/harbor" - "go-deploy/service/core" - sErrors "go-deploy/service/errors" - "go-deploy/service/generators" - "go-deploy/service/v2/deployments/client" - "go-deploy/service/v2/deployments/opts" - "go-deploy/service/v2/deployments/resources" - "go-deploy/utils/subsystemutils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor" + "github.com/kthcloud/go-deploy/service/core" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/generators" + "github.com/kthcloud/go-deploy/service/v2/deployments/client" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/service/v2/deployments/resources" + "github.com/kthcloud/go-deploy/utils/subsystemutils" ) // OptsAll returns the options required to get all the service tools, ie. deployment, client, and generator. diff --git a/service/v2/deployments/harbor_service/harbor_service.go b/service/v2/deployments/harbor_service/harbor_service.go index 9eacd3cd..ad79d1a0 100644 --- a/service/v2/deployments/harbor_service/harbor_service.go +++ b/service/v2/deployments/harbor_service/harbor_service.go @@ -2,14 +2,14 @@ package harbor_service import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" - "go-deploy/pkg/subsystems/harbor/models" - "go-deploy/service/resources" - "go-deploy/service/v2/deployments/opts" - "go-deploy/utils/subsystemutils" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" + "github.com/kthcloud/go-deploy/service/resources" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/utils/subsystemutils" "time" ) diff --git a/service/v2/deployments/hook_service.go b/service/v2/deployments/hook_service.go index fe0c3956..9b465e3d 100644 --- a/service/v2/deployments/hook_service.go +++ b/service/v2/deployments/hook_service.go @@ -1,7 +1,7 @@ package deployments import ( - "go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/config" ) // ValidateHarborToken validates the Harbor token. diff --git a/service/v2/deployments/k8s_service/client.go b/service/v2/deployments/k8s_service/client.go index e605b6a2..2ea6737a 100644 --- a/service/v2/deployments/k8s_service/client.go +++ b/service/v2/deployments/k8s_service/client.go @@ -1,16 +1,16 @@ package k8s_service import ( - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/service/core" - sErrors "go-deploy/service/errors" - "go-deploy/service/generators" - "go-deploy/service/v2/deployments/client" - "go-deploy/service/v2/deployments/opts" - "go-deploy/service/v2/deployments/resources" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/service/core" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/generators" + "github.com/kthcloud/go-deploy/service/v2/deployments/client" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/service/v2/deployments/resources" ) func OptsAll(deploymentID string, overwriteOps ...opts.ExtraOpts) *opts.Opts { diff --git a/service/v2/deployments/k8s_service/k8s_service.go b/service/v2/deployments/k8s_service/k8s_service.go index 5bcea6ec..f53b0459 100644 --- a/service/v2/deployments/k8s_service/k8s_service.go +++ b/service/v2/deployments/k8s_service/k8s_service.go @@ -4,18 +4,18 @@ import ( "context" "errors" "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" - kErrors "go-deploy/pkg/subsystems/k8s/errors" - k8sModels "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/constants" - sErrors "go-deploy/service/errors" - "go-deploy/service/resources" - "go-deploy/service/v2/deployments/opts" - "go-deploy/utils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" + kErrors "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/errors" + k8sModels "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/constants" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/resources" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/utils" "slices" "time" ) diff --git a/service/v2/deployments/logs_service.go b/service/v2/deployments/logs_service.go index 8db9e927..1d0a2d66 100644 --- a/service/v2/deployments/logs_service.go +++ b/service/v2/deployments/logs_service.go @@ -3,11 +3,11 @@ package deployments import ( "context" "fmt" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/log" - "go-deploy/service/errors" - "go-deploy/service/v2/deployments/opts" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/v2/deployments/opts" + "github.com/kthcloud/go-deploy/utils" "time" ) diff --git a/service/v2/deployments/opts/opts.go b/service/v2/deployments/opts/opts.go index 8b29095b..7bafcdc3 100644 --- a/service/v2/deployments/opts/opts.go +++ b/service/v2/deployments/opts/opts.go @@ -1,9 +1,9 @@ package opts import ( - body2 "go-deploy/dto/v2/body" - configModels "go-deploy/models/config" - v1 "go-deploy/service/v2/utils" + body2 "github.com/kthcloud/go-deploy/dto/v2/body" + configModels "github.com/kthcloud/go-deploy/models/config" + v1 "github.com/kthcloud/go-deploy/service/v2/utils" ) // Opts is used to specify which resources to get. diff --git a/service/v2/deployments/resources/harbor_generator.go b/service/v2/deployments/resources/harbor_generator.go index 1133d198..c46c43aa 100644 --- a/service/v2/deployments/resources/harbor_generator.go +++ b/service/v2/deployments/resources/harbor_generator.go @@ -3,12 +3,12 @@ package resources import ( "fmt" "github.com/google/uuid" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems" - "go-deploy/pkg/subsystems/harbor/models" - "go-deploy/service/generators" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" + "github.com/kthcloud/go-deploy/service/generators" "strings" ) diff --git a/service/v2/deployments/resources/k8s_generator.go b/service/v2/deployments/resources/k8s_generator.go index ca79679b..e2c9a00a 100644 --- a/service/v2/deployments/resources/k8s_generator.go +++ b/service/v2/deployments/resources/k8s_generator.go @@ -4,18 +4,18 @@ import ( "encoding/base64" "encoding/json" "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/team_repo" - "go-deploy/pkg/db/resources/user_repo" - "go-deploy/pkg/subsystems" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/constants" - "go-deploy/service/generators" - "go-deploy/utils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/team_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/constants" + "github.com/kthcloud/go-deploy/service/generators" + "github.com/kthcloud/go-deploy/utils" v1 "k8s.io/api/core/v1" "math" "path" diff --git a/service/v2/discovery/api_client.go b/service/v2/discovery/api_client.go index 745b0993..0b9ed38b 100644 --- a/service/v2/discovery/api_client.go +++ b/service/v2/discovery/api_client.go @@ -1,8 +1,8 @@ package discovery import ( - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" ) type Client struct { diff --git a/service/v2/discovery/discover_service.go b/service/v2/discovery/discover_service.go index 7548dc7c..4ff1389d 100644 --- a/service/v2/discovery/discover_service.go +++ b/service/v2/discovery/discover_service.go @@ -1,9 +1,9 @@ package discovery import ( - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" ) // Discover returns the discover information. diff --git a/service/v2/events/api_client.go b/service/v2/events/api_client.go index 2c587d4d..a40df276 100644 --- a/service/v2/events/api_client.go +++ b/service/v2/events/api_client.go @@ -1,8 +1,8 @@ package events import ( - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" ) type Client struct { diff --git a/service/v2/events/event_service.go b/service/v2/events/event_service.go index 53ffd3bf..1dea5622 100644 --- a/service/v2/events/event_service.go +++ b/service/v2/events/event_service.go @@ -1,8 +1,8 @@ package events import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/event_repo" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/event_repo" ) // Create creates a new event. diff --git a/service/v2/jobs/api_client.go b/service/v2/jobs/api_client.go index a1eed836..799354f0 100644 --- a/service/v2/jobs/api_client.go +++ b/service/v2/jobs/api_client.go @@ -1,10 +1,10 @@ package jobs import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/job_repo" - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" ) // Client is the client for the Job service. diff --git a/service/v2/jobs/job_service.go b/service/v2/jobs/job_service.go index f0f20742..6da3bbd5 100644 --- a/service/v2/jobs/job_service.go +++ b/service/v2/jobs/job_service.go @@ -1,12 +1,12 @@ package jobs import ( - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/job_repo" - sErrors "go-deploy/service/errors" - "go-deploy/service/utils" - "go-deploy/service/v2/jobs/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/jobs/opts" ) // Get retrieves a job by ID. diff --git a/service/v2/jobs/opts/opts.go b/service/v2/jobs/opts/opts.go index 73a2322f..b9048f3a 100644 --- a/service/v2/jobs/opts/opts.go +++ b/service/v2/jobs/opts/opts.go @@ -1,7 +1,7 @@ package opts import ( - "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/utils" ) // GetOpts is used to pass options to the Get method diff --git a/service/v2/notifications/api_client.go b/service/v2/notifications/api_client.go index 1a19c566..39c7329e 100644 --- a/service/v2/notifications/api_client.go +++ b/service/v2/notifications/api_client.go @@ -1,10 +1,10 @@ package notifications import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/notification_repo" - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/notification_repo" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" "sort" ) diff --git a/service/v2/notifications/notification_service.go b/service/v2/notifications/notification_service.go index 43db5553..cdc072d3 100644 --- a/service/v2/notifications/notification_service.go +++ b/service/v2/notifications/notification_service.go @@ -1,12 +1,12 @@ package notifications import ( - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/notification_repo" - sErrors "go-deploy/service/errors" - "go-deploy/service/utils" - "go-deploy/service/v2/notifications/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/notification_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/notifications/opts" ) // Get retrieves a notification by ID. diff --git a/service/v2/notifications/opts/opts.go b/service/v2/notifications/opts/opts.go index e77e2452..f34bc8eb 100644 --- a/service/v2/notifications/opts/opts.go +++ b/service/v2/notifications/opts/opts.go @@ -1,7 +1,7 @@ package opts import ( - "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/utils" ) // GetOpts is used to pass options to the Get method diff --git a/service/v2/resource_migrations/api_client.go b/service/v2/resource_migrations/api_client.go index 4a1285d7..718c3492 100644 --- a/service/v2/resource_migrations/api_client.go +++ b/service/v2/resource_migrations/api_client.go @@ -1,8 +1,8 @@ package resource_migrations import ( - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" ) type Client struct { diff --git a/service/v2/resource_migrations/opts/opts.go b/service/v2/resource_migrations/opts/opts.go index aa26ae40..b1307704 100644 --- a/service/v2/resource_migrations/opts/opts.go +++ b/service/v2/resource_migrations/opts/opts.go @@ -1,6 +1,6 @@ package opts -import v1 "go-deploy/service/v2/utils" +import v1 "github.com/kthcloud/go-deploy/service/v2/utils" // GetOpts is used to specify the options when getting a resource migration. type GetOpts struct { diff --git a/service/v2/resource_migrations/resource_migration_service.go b/service/v2/resource_migrations/resource_migration_service.go index 32ef62c6..8635f39d 100644 --- a/service/v2/resource_migrations/resource_migration_service.go +++ b/service/v2/resource_migrations/resource_migration_service.go @@ -4,17 +4,17 @@ import ( "errors" "fmt" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/db" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/resource_migration_repo" - "go-deploy/pkg/db/resources/vm_repo" - sErrors "go-deploy/service/errors" - sUtils "go-deploy/service/utils" - "go-deploy/service/v2/resource_migrations/opts" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/db" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/resource_migration_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" + sUtils "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/resource_migrations/opts" + "github.com/kthcloud/go-deploy/utils" ) // Get retrieves a resource migration by ID. diff --git a/service/v2/sms/api_client.go b/service/v2/sms/api_client.go index 03fd8a9b..47f7a013 100644 --- a/service/v2/sms/api_client.go +++ b/service/v2/sms/api_client.go @@ -1,10 +1,10 @@ package sms import ( - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2/sms/client" - "go-deploy/service/v2/sms/k8s_service" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/sms/client" + "github.com/kthcloud/go-deploy/service/v2/sms/k8s_service" ) // Client is the client for the Deployment service. diff --git a/service/v2/sms/client/client.go b/service/v2/sms/client/client.go index 12616a74..2dafd620 100644 --- a/service/v2/sms/client/client.go +++ b/service/v2/sms/client/client.go @@ -2,9 +2,9 @@ package client import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/sm_repo" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" + "github.com/kthcloud/go-deploy/service/core" ) // BaseClient is the base client for all the subsystems client for SMs. diff --git a/service/v2/sms/k8s_service/client.go b/service/v2/sms/k8s_service/client.go index 44edaf9a..1839e758 100644 --- a/service/v2/sms/k8s_service/client.go +++ b/service/v2/sms/k8s_service/client.go @@ -1,16 +1,16 @@ package k8s_service import ( - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/service/core" - sErrors "go-deploy/service/errors" - "go-deploy/service/generators" - "go-deploy/service/v2/sms/client" - "go-deploy/service/v2/sms/opts" - "go-deploy/service/v2/sms/resources" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/service/core" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/generators" + "github.com/kthcloud/go-deploy/service/v2/sms/client" + "github.com/kthcloud/go-deploy/service/v2/sms/opts" + "github.com/kthcloud/go-deploy/service/v2/sms/resources" ) // OptsAll returns the options required to get all the service tools, ie. SM, client, and generator. diff --git a/service/v2/sms/k8s_service/k8s_service.go b/service/v2/sms/k8s_service/k8s_service.go index 8d513c33..2143ee5d 100644 --- a/service/v2/sms/k8s_service/k8s_service.go +++ b/service/v2/sms/k8s_service/k8s_service.go @@ -3,14 +3,14 @@ package k8s_service import ( "errors" "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/sm_repo" - "go-deploy/pkg/log" - kErrors "go-deploy/pkg/subsystems/k8s/errors" - k8sModels "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/constants" - sErrors "go-deploy/service/errors" - "go-deploy/service/resources" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + kErrors "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/errors" + k8sModels "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/constants" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/resources" "golang.org/x/exp/slices" ) diff --git a/service/v2/sms/opts/opts.go b/service/v2/sms/opts/opts.go index b0d1e3a3..7a4f09d3 100644 --- a/service/v2/sms/opts/opts.go +++ b/service/v2/sms/opts/opts.go @@ -1,8 +1,8 @@ package opts import ( - configModels "go-deploy/models/config" - "go-deploy/service/v2/utils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/service/v2/utils" ) // Opts is used to specify which resources to get. diff --git a/service/v2/sms/resources/k8s_generator.go b/service/v2/sms/resources/k8s_generator.go index a9a8648d..7f95bbda 100644 --- a/service/v2/sms/resources/k8s_generator.go +++ b/service/v2/sms/resources/k8s_generator.go @@ -2,17 +2,17 @@ package resources import ( "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/user_repo" - "go-deploy/pkg/subsystems" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/constants" - "go-deploy/service/generators" - "go-deploy/utils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/constants" + "github.com/kthcloud/go-deploy/service/generators" + "github.com/kthcloud/go-deploy/utils" v1 "k8s.io/api/core/v1" "math" "path" diff --git a/service/v2/sms/sm_service.go b/service/v2/sms/sm_service.go index 09f313e4..8db78c99 100644 --- a/service/v2/sms/sm_service.go +++ b/service/v2/sms/sm_service.go @@ -3,15 +3,15 @@ package sms import ( "errors" "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/sm_repo" - "go-deploy/pkg/log" - sErrors "go-deploy/service/errors" - "go-deploy/service/utils" - "go-deploy/service/v2/sms/k8s_service" - "go-deploy/service/v2/sms/opts" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/sms/k8s_service" + "github.com/kthcloud/go-deploy/service/v2/sms/opts" "sort" "strconv" "strings" diff --git a/service/v2/system/api_client.go b/service/v2/system/api_client.go index 43a771b0..d3497378 100644 --- a/service/v2/system/api_client.go +++ b/service/v2/system/api_client.go @@ -1,8 +1,8 @@ package system import ( - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" ) type Client struct { diff --git a/service/v2/system/host_service.go b/service/v2/system/host_service.go index a3a866e7..f6079b6c 100644 --- a/service/v2/system/host_service.go +++ b/service/v2/system/host_service.go @@ -1,8 +1,8 @@ package system import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/host_repo" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" ) // ListHosts gets a list of hosts diff --git a/service/v2/system/registration_service.go b/service/v2/system/registration_service.go index 53a72c0d..e44d2754 100644 --- a/service/v2/system/registration_service.go +++ b/service/v2/system/registration_service.go @@ -1,11 +1,11 @@ package system import ( - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/host_repo" - sErrors "go-deploy/service/errors" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" ) func (c *Client) RegisterNode(params *body.HostRegisterParams) error { diff --git a/service/v2/system/system_service.go b/service/v2/system/system_service.go index 388929b3..40024e87 100644 --- a/service/v2/system/system_service.go +++ b/service/v2/system/system_service.go @@ -2,10 +2,10 @@ package system import ( "fmt" - "go-deploy/dto/v2/body" - "go-deploy/pkg/db/resources/system_capacities_repo" - "go-deploy/pkg/db/resources/system_stats_repo" - "go-deploy/pkg/db/resources/system_status_repo" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_capacities_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_stats_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/system_status_repo" ) // ListCapacities fetches the system capacities from the database. diff --git a/service/v2/system/worker_service.go b/service/v2/system/worker_service.go index dd84f2b0..8f6f9695 100644 --- a/service/v2/system/worker_service.go +++ b/service/v2/system/worker_service.go @@ -1,9 +1,9 @@ package system import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/worker_status_repo" - "go-deploy/service/v2/system/opts" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/worker_status_repo" + "github.com/kthcloud/go-deploy/service/v2/system/opts" "time" ) diff --git a/service/v2/system/zone_service.go b/service/v2/system/zone_service.go index b48d7e02..b96aeaa9 100644 --- a/service/v2/system/zone_service.go +++ b/service/v2/system/zone_service.go @@ -1,10 +1,10 @@ package system import ( - configModels "go-deploy/models/config" - "go-deploy/pkg/config" - "go-deploy/service/utils" - "go-deploy/service/v2/system/opts" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/system/opts" ) // GetZone gets a zone by name and type diff --git a/service/v2/teams/api_client.go b/service/v2/teams/api_client.go index 57a76f59..3cbe8b3b 100644 --- a/service/v2/teams/api_client.go +++ b/service/v2/teams/api_client.go @@ -1,11 +1,11 @@ package teams import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/team_repo" - "go-deploy/pkg/db/resources/user_repo" - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/team_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" "sort" ) diff --git a/service/v2/teams/opts/opts.go b/service/v2/teams/opts/opts.go index 5f43a808..3dc4ee74 100644 --- a/service/v2/teams/opts/opts.go +++ b/service/v2/teams/opts/opts.go @@ -1,7 +1,7 @@ package opts import ( - "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/utils" ) // GetOpts is used to pass options to the Get method diff --git a/service/v2/teams/team_service.go b/service/v2/teams/team_service.go index 30c8cef2..59c25e8a 100644 --- a/service/v2/teams/team_service.go +++ b/service/v2/teams/team_service.go @@ -4,16 +4,16 @@ import ( "errors" "fmt" "github.com/google/uuid" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/deployment_repo" - "go-deploy/pkg/db/resources/notification_repo" - "go-deploy/pkg/db/resources/team_repo" - "go-deploy/pkg/db/resources/vm_repo" - sErrors "go-deploy/service/errors" - utils2 "go-deploy/service/utils" - "go-deploy/service/v2/teams/opts" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/notification_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/team_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" + utils2 "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/teams/opts" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "time" ) diff --git a/service/v2/users/api_client.go b/service/v2/users/api_client.go index a58d5655..b398cfea 100644 --- a/service/v2/users/api_client.go +++ b/service/v2/users/api_client.go @@ -1,13 +1,13 @@ package users import ( - "go-deploy/models/model" - "go-deploy/pkg/db/resources/team_repo" - "go-deploy/pkg/db/resources/user_repo" - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2/api" - "go-deploy/service/v2/users/api_key" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/team_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/api" + "github.com/kthcloud/go-deploy/service/v2/users/api_key" "sort" ) diff --git a/service/v2/users/api_key/api_key.go b/service/v2/users/api_key/api_key.go index 01c55026..e8e74f40 100644 --- a/service/v2/users/api_key/api_key.go +++ b/service/v2/users/api_key/api_key.go @@ -1,11 +1,11 @@ package api_key import ( - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/user_repo" - sErrors "go-deploy/service/errors" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/utils" "time" ) diff --git a/service/v2/users/api_key/client.go b/service/v2/users/api_key/client.go index 8665b127..dc72f4ab 100644 --- a/service/v2/users/api_key/client.go +++ b/service/v2/users/api_key/client.go @@ -1,8 +1,8 @@ package api_key import ( - "go-deploy/service/clients" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" ) type Client struct { diff --git a/service/v2/users/opts/opts.go b/service/v2/users/opts/opts.go index 3f2107b9..e43f50dd 100644 --- a/service/v2/users/opts/opts.go +++ b/service/v2/users/opts/opts.go @@ -1,7 +1,7 @@ package opts import ( - "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/service/v2/utils" ) // GetOpts is used to pass options to the Get method diff --git a/service/v2/users/user_service.go b/service/v2/users/user_service.go index 91d81b2f..c2706c59 100644 --- a/service/v2/users/user_service.go +++ b/service/v2/users/user_service.go @@ -3,13 +3,13 @@ package users import ( "crypto/sha256" "encoding/hex" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/user_repo" - sErrors "go-deploy/service/errors" - "go-deploy/service/utils" - "go-deploy/service/v2/users/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/users/opts" "net/http" "strings" "time" diff --git a/service/v2/utils/utils.go b/service/v2/utils/utils.go index 7546e7d9..4d8525e8 100644 --- a/service/v2/utils/utils.go +++ b/service/v2/utils/utils.go @@ -1,6 +1,6 @@ package utils -import "go-deploy/dto/v2/query" +import "github.com/kthcloud/go-deploy/dto/v2/query" type Pagination struct { Page int diff --git a/service/v2/vms/api_client.go b/service/v2/vms/api_client.go index 46eac8fa..fd7deae0 100644 --- a/service/v2/vms/api_client.go +++ b/service/v2/vms/api_client.go @@ -1,14 +1,14 @@ package vms import ( - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2/api" - "go-deploy/service/v2/vms/client" - "go-deploy/service/v2/vms/gpu_groups" - "go-deploy/service/v2/vms/gpu_leases" - "go-deploy/service/v2/vms/k8s_service" - "go-deploy/service/v2/vms/snapshots" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/api" + "github.com/kthcloud/go-deploy/service/v2/vms/client" + "github.com/kthcloud/go-deploy/service/v2/vms/gpu_groups" + "github.com/kthcloud/go-deploy/service/v2/vms/gpu_leases" + "github.com/kthcloud/go-deploy/service/v2/vms/k8s_service" + "github.com/kthcloud/go-deploy/service/v2/vms/snapshots" ) // Client is the client for the Deployment service. diff --git a/service/v2/vms/client/client.go b/service/v2/vms/client/client.go index 4b6c1c88..72c834fe 100644 --- a/service/v2/vms/client/client.go +++ b/service/v2/vms/client/client.go @@ -2,10 +2,10 @@ package client import ( "fmt" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/service/core" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/service/core" ) // BaseClient is the base client for all the subsystems client for VMs and GPUs. diff --git a/service/v2/vms/gpu_groups/client.go b/service/v2/vms/gpu_groups/client.go index aa7b585b..dc5e70c7 100644 --- a/service/v2/vms/gpu_groups/client.go +++ b/service/v2/vms/gpu_groups/client.go @@ -1,9 +1,9 @@ package gpu_groups import ( - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2/vms/client" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/vms/client" ) type Client struct { diff --git a/service/v2/vms/gpu_groups/gpu_groups_service.go b/service/v2/vms/gpu_groups/gpu_groups_service.go index d5282963..fd02f172 100644 --- a/service/v2/vms/gpu_groups/gpu_groups_service.go +++ b/service/v2/vms/gpu_groups/gpu_groups_service.go @@ -2,10 +2,10 @@ package gpu_groups import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/gpu_group_repo" - sUtils "go-deploy/service/utils" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/gpu_group_repo" + sUtils "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" ) // Get gets a GPU group by ID diff --git a/service/v2/vms/gpu_leases/client.go b/service/v2/vms/gpu_leases/client.go index 5c035c88..966e2001 100644 --- a/service/v2/vms/gpu_leases/client.go +++ b/service/v2/vms/gpu_leases/client.go @@ -1,9 +1,9 @@ package gpu_leases import ( - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2/vms/client" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/vms/client" ) type Client struct { diff --git a/service/v2/vms/gpu_leases/gpu_lease_service.go b/service/v2/vms/gpu_leases/gpu_lease_service.go index 341bbb1e..482960a1 100644 --- a/service/v2/vms/gpu_leases/gpu_lease_service.go +++ b/service/v2/vms/gpu_leases/gpu_lease_service.go @@ -3,12 +3,12 @@ package gpu_leases import ( "errors" "fmt" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/db/resources/gpu_lease_repo" - sErrors "go-deploy/service/errors" - sUtils "go-deploy/service/utils" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/db/resources/gpu_lease_repo" + sErrors "github.com/kthcloud/go-deploy/service/errors" + sUtils "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" "time" ) diff --git a/service/v2/vms/k8s_service/client.go b/service/v2/vms/k8s_service/client.go index a9c63752..ecf61141 100644 --- a/service/v2/vms/k8s_service/client.go +++ b/service/v2/vms/k8s_service/client.go @@ -2,16 +2,16 @@ package k8s_service import ( "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/service/core" - sErrors "go-deploy/service/errors" - "go-deploy/service/generators" - "go-deploy/service/v2/vms/client" - "go-deploy/service/v2/vms/opts" - "go-deploy/service/v2/vms/resources" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/service/core" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/generators" + "github.com/kthcloud/go-deploy/service/v2/vms/client" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/service/v2/vms/resources" ) // OptsAll returns the options required to get all the service tools, ie. VM, client and generator. diff --git a/service/v2/vms/k8s_service/k8s_service.go b/service/v2/vms/k8s_service/k8s_service.go index ff2b9aed..e1f7300e 100644 --- a/service/v2/vms/k8s_service/k8s_service.go +++ b/service/v2/vms/k8s_service/k8s_service.go @@ -4,20 +4,20 @@ import ( "context" "errors" "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - "go-deploy/pkg/db/resources/vm_port_repo" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" - "go-deploy/pkg/subsystems" - kErrors "go-deploy/pkg/subsystems/k8s/errors" - k8sModels "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/constants" - sErrors "go-deploy/service/errors" - "go-deploy/service/resources" - "go-deploy/service/v2/vms/opts" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_port_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/subsystems" + kErrors "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/errors" + k8sModels "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/constants" + sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/kthcloud/go-deploy/service/resources" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" "golang.org/x/exp/slices" ) diff --git a/service/v2/vms/k8s_service/snapshot_service.go b/service/v2/vms/k8s_service/snapshot_service.go index 865d9f10..7341c08d 100644 --- a/service/v2/vms/k8s_service/snapshot_service.go +++ b/service/v2/vms/k8s_service/snapshot_service.go @@ -2,10 +2,10 @@ package k8s_service import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/subsystems" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/resources" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/resources" ) func (c *Client) CreateVmSnapshot(vmID string, params *model.CreateSnapshotParams) (*model.SnapshotV2, error) { diff --git a/service/v2/vms/opts/opts.go b/service/v2/vms/opts/opts.go index bf935442..5274ed7a 100644 --- a/service/v2/vms/opts/opts.go +++ b/service/v2/vms/opts/opts.go @@ -1,10 +1,10 @@ package opts import ( - "go-deploy/dto/v2/body" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/service/v2/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/service/v2/utils" "time" ) diff --git a/service/v2/vms/resources/k8s_generator.go b/service/v2/vms/resources/k8s_generator.go index e8225076..4e83e5a9 100644 --- a/service/v2/vms/resources/k8s_generator.go +++ b/service/v2/vms/resources/k8s_generator.go @@ -2,16 +2,16 @@ package resources import ( "fmt" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/pkg/subsystems/k8s/keys" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/service/constants" - "go-deploy/service/generators" - "go-deploy/utils" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/service/constants" + "github.com/kthcloud/go-deploy/service/generators" + "github.com/kthcloud/go-deploy/utils" "gopkg.in/yaml.v3" v1 "k8s.io/api/core/v1" "slices" diff --git a/service/v2/vms/snapshots/client.go b/service/v2/vms/snapshots/client.go index bd0dfe53..1541da01 100644 --- a/service/v2/vms/snapshots/client.go +++ b/service/v2/vms/snapshots/client.go @@ -1,9 +1,9 @@ package snapshots import ( - "go-deploy/service/clients" - "go-deploy/service/core" - "go-deploy/service/v2/vms/client" + "github.com/kthcloud/go-deploy/service/clients" + "github.com/kthcloud/go-deploy/service/core" + "github.com/kthcloud/go-deploy/service/v2/vms/client" ) type Client struct { diff --git a/service/v2/vms/snapshots/snapshot_service.go b/service/v2/vms/snapshots/snapshot_service.go index 18f1e105..582e4587 100644 --- a/service/v2/vms/snapshots/snapshot_service.go +++ b/service/v2/vms/snapshots/snapshot_service.go @@ -2,10 +2,10 @@ package snapshots import ( "fmt" - "go-deploy/models/model" - "go-deploy/pkg/log" - "go-deploy/service/utils" - "go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" "sort" ) diff --git a/service/v2/vms/vm_service.go b/service/v2/vms/vm_service.go index 27708db3..c1ece24e 100644 --- a/service/v2/vms/vm_service.go +++ b/service/v2/vms/vm_service.go @@ -3,23 +3,23 @@ package vms import ( "errors" "fmt" - "go-deploy/dto/v2/body" - configModels "go-deploy/models/config" - "go-deploy/models/model" - "go-deploy/models/version" - "go-deploy/pkg/config" - rErrors "go-deploy/pkg/db/resources/errors" - "go-deploy/pkg/db/resources/gpu_lease_repo" - "go-deploy/pkg/db/resources/notification_repo" - "go-deploy/pkg/db/resources/resource_migration_repo" - "go-deploy/pkg/db/resources/team_repo" - "go-deploy/pkg/db/resources/vm_port_repo" - "go-deploy/pkg/db/resources/vm_repo" - "go-deploy/pkg/log" - sErrors "go-deploy/service/errors" - serviceUtils "go-deploy/service/utils" - "go-deploy/service/v2/vms/opts" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/dto/v2/body" + configModels "github.com/kthcloud/go-deploy/models/config" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/models/version" + "github.com/kthcloud/go-deploy/pkg/config" + rErrors "github.com/kthcloud/go-deploy/pkg/db/resources/errors" + "github.com/kthcloud/go-deploy/pkg/db/resources/gpu_lease_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/notification_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/resource_migration_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/team_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_port_repo" + "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" + "github.com/kthcloud/go-deploy/pkg/log" + sErrors "github.com/kthcloud/go-deploy/service/errors" + serviceUtils "github.com/kthcloud/go-deploy/service/utils" + "github.com/kthcloud/go-deploy/service/v2/vms/opts" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "sort" "strings" diff --git a/test/acc/common.go b/test/acc/common.go index 0a486777..200d50e6 100644 --- a/test/acc/common.go +++ b/test/acc/common.go @@ -2,9 +2,9 @@ package acc import ( "fmt" - "go-deploy/models/mode" - "go-deploy/pkg/config" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/models/mode" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/log" "os" "strings" diff --git a/test/acc/subsystems/harbor/helpers.go b/test/acc/subsystems/harbor/helpers.go index 509e52b2..4d8e36ec 100644 --- a/test/acc/subsystems/harbor/helpers.go +++ b/test/acc/subsystems/harbor/helpers.go @@ -2,11 +2,11 @@ package harbor import ( "github.com/stretchr/testify/assert" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems/harbor" - "go-deploy/pkg/subsystems/harbor/models" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" "strings" "testing" ) diff --git a/test/acc/subsystems/harbor/main_test.go b/test/acc/subsystems/harbor/main_test.go index afefadb6..c8932a54 100644 --- a/test/acc/subsystems/harbor/main_test.go +++ b/test/acc/subsystems/harbor/main_test.go @@ -1,7 +1,7 @@ package harbor import ( - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/test/acc" "log" "os" "testing" diff --git a/test/acc/subsystems/harbor/project_test.go b/test/acc/subsystems/harbor/project_test.go index 69eec1f0..6dabe91c 100644 --- a/test/acc/subsystems/harbor/project_test.go +++ b/test/acc/subsystems/harbor/project_test.go @@ -2,7 +2,7 @@ package harbor import ( "github.com/stretchr/testify/assert" - "go-deploy/test" + "github.com/kthcloud/go-deploy/test" "testing" ) diff --git a/test/acc/subsystems/harbor/robot_test.go b/test/acc/subsystems/harbor/robot_test.go index e23c3bd9..a6ca0f46 100644 --- a/test/acc/subsystems/harbor/robot_test.go +++ b/test/acc/subsystems/harbor/robot_test.go @@ -2,9 +2,9 @@ package harbor import ( "github.com/stretchr/testify/assert" - "go-deploy/pkg/subsystems/harbor/models" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" "testing" ) diff --git a/test/acc/subsystems/harbor/webhook_test.go b/test/acc/subsystems/harbor/webhook_test.go index 7d9d8050..f2ca2ca0 100644 --- a/test/acc/subsystems/harbor/webhook_test.go +++ b/test/acc/subsystems/harbor/webhook_test.go @@ -2,8 +2,8 @@ package harbor import ( "github.com/stretchr/testify/assert" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" "testing" ) diff --git a/test/acc/subsystems/k8s/deployment_test.go b/test/acc/subsystems/k8s/deployment_test.go index 72124a5d..b0eea882 100644 --- a/test/acc/subsystems/k8s/deployment_test.go +++ b/test/acc/subsystems/k8s/deployment_test.go @@ -1,9 +1,9 @@ package k8s import ( - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" "testing" ) diff --git a/test/acc/subsystems/k8s/helpers.go b/test/acc/subsystems/k8s/helpers.go index f1e64be2..24d8930f 100644 --- a/test/acc/subsystems/k8s/helpers.go +++ b/test/acc/subsystems/k8s/helpers.go @@ -2,11 +2,11 @@ package k8s import ( "github.com/stretchr/testify/assert" - "go-deploy/pkg/config" - "go-deploy/pkg/subsystems/k8s" - "go-deploy/pkg/subsystems/k8s/models" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" v1 "k8s.io/api/core/v1" "testing" ) diff --git a/test/acc/subsystems/k8s/hpa_test.go b/test/acc/subsystems/k8s/hpa_test.go index bc568915..68a4a8e3 100644 --- a/test/acc/subsystems/k8s/hpa_test.go +++ b/test/acc/subsystems/k8s/hpa_test.go @@ -2,7 +2,7 @@ package k8s import ( "github.com/stretchr/testify/assert" - "go-deploy/test" + "github.com/kthcloud/go-deploy/test" "testing" ) diff --git a/test/acc/subsystems/k8s/ingress_test.go b/test/acc/subsystems/k8s/ingress_test.go index c0447cb4..a1c9d8f8 100644 --- a/test/acc/subsystems/k8s/ingress_test.go +++ b/test/acc/subsystems/k8s/ingress_test.go @@ -2,8 +2,8 @@ package k8s import ( "github.com/stretchr/testify/assert" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" "testing" ) diff --git a/test/acc/subsystems/k8s/main_test.go b/test/acc/subsystems/k8s/main_test.go index d5241c2c..e23bace0 100644 --- a/test/acc/subsystems/k8s/main_test.go +++ b/test/acc/subsystems/k8s/main_test.go @@ -1,7 +1,7 @@ package k8s import ( - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/test/acc" "log" "os" "testing" diff --git a/test/acc/subsystems/k8s/network_policy_test.go b/test/acc/subsystems/k8s/network_policy_test.go index ac239d59..bcc65c6a 100644 --- a/test/acc/subsystems/k8s/network_policy_test.go +++ b/test/acc/subsystems/k8s/network_policy_test.go @@ -2,7 +2,7 @@ package k8s import ( "github.com/stretchr/testify/assert" - "go-deploy/pkg/subsystems/k8s/models" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" "testing" ) diff --git a/test/acc/subsystems/k8s/secret_test.go b/test/acc/subsystems/k8s/secret_test.go index 0d5be8b8..bc9334e9 100644 --- a/test/acc/subsystems/k8s/secret_test.go +++ b/test/acc/subsystems/k8s/secret_test.go @@ -2,8 +2,8 @@ package k8s import ( "github.com/stretchr/testify/assert" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" "testing" ) diff --git a/test/acc/subsystems/k8s/service_test.go b/test/acc/subsystems/k8s/service_test.go index 7f552097..da7fa69c 100644 --- a/test/acc/subsystems/k8s/service_test.go +++ b/test/acc/subsystems/k8s/service_test.go @@ -2,7 +2,7 @@ package k8s import ( "github.com/stretchr/testify/assert" - "go-deploy/test" + "github.com/kthcloud/go-deploy/test" "testing" ) diff --git a/test/acc/subsystems/k8s/vm_test.go b/test/acc/subsystems/k8s/vm_test.go index 43e7bb45..041fb4f6 100644 --- a/test/acc/subsystems/k8s/vm_test.go +++ b/test/acc/subsystems/k8s/vm_test.go @@ -2,8 +2,8 @@ package k8s import ( "github.com/stretchr/testify/assert" - "go-deploy/test" - "go-deploy/test/acc" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/acc" "testing" ) diff --git a/test/e2e/common.go b/test/e2e/common.go index d381ff02..e937553b 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -6,9 +6,9 @@ import ( "fmt" "github.com/google/uuid" "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/sys" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/sys" "io" "net/http" "strings" diff --git a/test/e2e/setup.go b/test/e2e/setup.go index 689117a0..f2677a43 100644 --- a/test/e2e/setup.go +++ b/test/e2e/setup.go @@ -1,7 +1,7 @@ package e2e import ( - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/log" "os" ) diff --git a/test/e2e/v2/deployment_utils.go b/test/e2e/v2/deployment_utils.go index be7ba4be..8b5e8fe2 100644 --- a/test/e2e/v2/deployment_utils.go +++ b/test/e2e/v2/deployment_utils.go @@ -3,11 +3,11 @@ package v2 import ( "crypto/tls" "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/pkg/app/status_codes" - "go-deploy/test" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/e2e" "golang.org/x/net/idna" "net/http" "strconv" diff --git a/test/e2e/v2/deployments/routes_test.go b/test/e2e/v2/deployments/routes_test.go index c3a9a145..55be2322 100644 --- a/test/e2e/v2/deployments/routes_test.go +++ b/test/e2e/v2/deployments/routes_test.go @@ -3,10 +3,10 @@ package deployments import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/test/e2e/v2" "net/http" "os" "strconv" diff --git a/test/e2e/v2/gpu_groups/routes_test.go b/test/e2e/v2/gpu_groups/routes_test.go index 586f7bdf..34b95293 100644 --- a/test/e2e/v2/gpu_groups/routes_test.go +++ b/test/e2e/v2/gpu_groups/routes_test.go @@ -1,8 +1,8 @@ package gpu_groups import ( - "go-deploy/test/e2e" - v2 "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/test/e2e" + v2 "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "testing" ) diff --git a/test/e2e/v2/gpu_groups_utils.go b/test/e2e/v2/gpu_groups_utils.go index 80ee4117..0bc6b518 100644 --- a/test/e2e/v2/gpu_groups_utils.go +++ b/test/e2e/v2/gpu_groups_utils.go @@ -1,8 +1,8 @@ package v2 import ( - "go-deploy/dto/v2/body" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/test/e2e" "testing" ) diff --git a/test/e2e/v2/gpu_leases/routes_test.go b/test/e2e/v2/gpu_leases/routes_test.go index b6895da6..3824e5c4 100644 --- a/test/e2e/v2/gpu_leases/routes_test.go +++ b/test/e2e/v2/gpu_leases/routes_test.go @@ -1,10 +1,10 @@ package gpu_leases import ( - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - v2 "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + v2 "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "testing" ) diff --git a/test/e2e/v2/gpu_leases_utils.go b/test/e2e/v2/gpu_leases_utils.go index e39972ae..0fa996fb 100644 --- a/test/e2e/v2/gpu_leases_utils.go +++ b/test/e2e/v2/gpu_leases_utils.go @@ -2,8 +2,8 @@ package v2 import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/test/e2e" "testing" ) diff --git a/test/e2e/v2/job_utils.go b/test/e2e/v2/job_utils.go index 5f5ad29e..2f2f1e65 100644 --- a/test/e2e/v2/job_utils.go +++ b/test/e2e/v2/job_utils.go @@ -2,9 +2,9 @@ package v2 import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/pkg/app/status_codes" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/test/e2e" "net/http" "testing" ) diff --git a/test/e2e/v2/jobs/routes_test.go b/test/e2e/v2/jobs/routes_test.go index fe60dffe..e15ff830 100644 --- a/test/e2e/v2/jobs/routes_test.go +++ b/test/e2e/v2/jobs/routes_test.go @@ -2,10 +2,10 @@ package jobs import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "testing" ) diff --git a/test/e2e/v2/notifications/route_test.go b/test/e2e/v2/notifications/route_test.go index bf93f9aa..7843e1a3 100644 --- a/test/e2e/v2/notifications/route_test.go +++ b/test/e2e/v2/notifications/route_test.go @@ -1,10 +1,10 @@ package notifications import ( - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "testing" ) diff --git a/test/e2e/v2/notifications_utils.go b/test/e2e/v2/notifications_utils.go index afc21987..56fd01f5 100644 --- a/test/e2e/v2/notifications_utils.go +++ b/test/e2e/v2/notifications_utils.go @@ -2,8 +2,8 @@ package v2 import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/test/e2e" "testing" ) diff --git a/test/e2e/v2/resource_migrations/route_test.go b/test/e2e/v2/resource_migrations/route_test.go index 77b8006f..48a964fb 100644 --- a/test/e2e/v2/resource_migrations/route_test.go +++ b/test/e2e/v2/resource_migrations/route_test.go @@ -2,10 +2,10 @@ package resource_migrations import ( "github.com/stretchr/testify/assert" - bodyV2 "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - v2 "go-deploy/test/e2e/v2" + bodyV2 "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + v2 "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "strings" "testing" diff --git a/test/e2e/v2/resource_migrations_utils.go b/test/e2e/v2/resource_migrations_utils.go index fa9c1802..4c80849a 100644 --- a/test/e2e/v2/resource_migrations_utils.go +++ b/test/e2e/v2/resource_migrations_utils.go @@ -2,9 +2,9 @@ package v2 import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" "net/http" "testing" ) diff --git a/test/e2e/v2/sm_utils.go b/test/e2e/v2/sm_utils.go index 681c8e9e..59162fb7 100644 --- a/test/e2e/v2/sm_utils.go +++ b/test/e2e/v2/sm_utils.go @@ -1,8 +1,8 @@ package v2 import ( - "go-deploy/dto/v2/body" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/test/e2e" "net/http" "testing" ) diff --git a/test/e2e/v2/sms/route_test.go b/test/e2e/v2/sms/route_test.go index 7204b5eb..f7fdcf6c 100644 --- a/test/e2e/v2/sms/route_test.go +++ b/test/e2e/v2/sms/route_test.go @@ -2,10 +2,10 @@ package sms import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "testing" "time" diff --git a/test/e2e/v2/team_utils.go b/test/e2e/v2/team_utils.go index 86644e35..3d9f05fb 100644 --- a/test/e2e/v2/team_utils.go +++ b/test/e2e/v2/team_utils.go @@ -2,10 +2,10 @@ package v2 import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/e2e" "net/http" "testing" ) diff --git a/test/e2e/v2/teams/routes_test.go b/test/e2e/v2/teams/routes_test.go index 6de20630..c18b6b88 100644 --- a/test/e2e/v2/teams/routes_test.go +++ b/test/e2e/v2/teams/routes_test.go @@ -2,10 +2,10 @@ package teams import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/test/e2e/v2" "net/http" "os" "testing" diff --git a/test/e2e/v2/user_utils.go b/test/e2e/v2/user_utils.go index 436d48b5..a0b472fb 100644 --- a/test/e2e/v2/user_utils.go +++ b/test/e2e/v2/user_utils.go @@ -2,9 +2,9 @@ package v2 import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/test" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/test" + "github.com/kthcloud/go-deploy/test/e2e" "testing" ) diff --git a/test/e2e/v2/users/routes_test.go b/test/e2e/v2/users/routes_test.go index b5bc5c06..8111add8 100644 --- a/test/e2e/v2/users/routes_test.go +++ b/test/e2e/v2/users/routes_test.go @@ -2,10 +2,10 @@ package users import ( "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "testing" "time" diff --git a/test/e2e/v2/vm_utils.go b/test/e2e/v2/vm_utils.go index d7f5cf90..77ffbf58 100644 --- a/test/e2e/v2/vm_utils.go +++ b/test/e2e/v2/vm_utils.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/helloyi/go-sshclient" "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/pkg/app/status_codes" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/pkg/app/status_codes" + "github.com/kthcloud/go-deploy/test/e2e" "net/http" "os" "strings" diff --git a/test/e2e/v2/vms/routes_test.go b/test/e2e/v2/vms/routes_test.go index 177eedc8..68b3456b 100644 --- a/test/e2e/v2/vms/routes_test.go +++ b/test/e2e/v2/vms/routes_test.go @@ -3,10 +3,10 @@ package vms import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" - "go-deploy/dto/v2/body" - "go-deploy/models/model" - "go-deploy/test/e2e" - "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/test/e2e/v2" "net/http" "os" "strings" diff --git a/test/e2e/v2/zone_utils.go b/test/e2e/v2/zone_utils.go index ba728ef7..82fb384c 100644 --- a/test/e2e/v2/zone_utils.go +++ b/test/e2e/v2/zone_utils.go @@ -1,8 +1,8 @@ package v2 import ( - "go-deploy/dto/v2/body" - "go-deploy/test/e2e" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/test/e2e" "testing" ) diff --git a/test/e2e/v2/zones/routes_test.go b/test/e2e/v2/zones/routes_test.go index 4ad70dd2..ff51eae0 100644 --- a/test/e2e/v2/zones/routes_test.go +++ b/test/e2e/v2/zones/routes_test.go @@ -1,8 +1,8 @@ package zones import ( - "go-deploy/test/e2e" - v1 "go-deploy/test/e2e/v2" + "github.com/kthcloud/go-deploy/test/e2e" + v1 "github.com/kthcloud/go-deploy/test/e2e/v2" "os" "testing" ) diff --git a/utils/requestutils/utils.go b/utils/requestutils/utils.go index d95dbc7a..e7fbd334 100644 --- a/utils/requestutils/utils.go +++ b/utils/requestutils/utils.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "fmt" - "go-deploy/utils" + "github.com/kthcloud/go-deploy/utils" "io" "net/http" ) diff --git a/utils/subsystemutils/utils.go b/utils/subsystemutils/utils.go index 4af07c7a..5324cb6e 100644 --- a/utils/subsystemutils/utils.go +++ b/utils/subsystemutils/utils.go @@ -2,7 +2,7 @@ package subsystemutils import ( "fmt" - "go-deploy/pkg/config" + "github.com/kthcloud/go-deploy/pkg/config" ) // GetPrefixedName returns the name with the prefix. diff --git a/utils/utils.go b/utils/utils.go index c3960b8d..2b0bfc34 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,7 +5,7 @@ import ( "encoding/base64" "errors" "fmt" - "go-deploy/pkg/log" + "github.com/kthcloud/go-deploy/pkg/log" "math/rand" "strings" "time" From 7261d6415d0e6a95a12259563a93d2b9031d6833 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Wed, 15 Jan 2025 23:23:55 +0100 Subject: [PATCH 03/36] updated OpenAPI spec to v 3.0 and added keycloak authentication to swagger ui --- .gitignore | 9 +- docs/api/v2/V2_docs.go | 507 ++- docs/api/v2/V2_swagger.json | 5176 +-------------------- docs/api/v2/V2_swagger.yaml | 5745 +++++++++++++----------- export/tygo.yml | 6 +- export/types/v2/body/index.ts | 67 +- export/types/v2/query/index.ts | 3 + main.go | 9 +- routers/api/v2/api_key.go | 2 + routers/api/v2/deployment.go | 10 +- routers/api/v2/deployment_ci_config.go | 4 +- routers/api/v2/deployment_command.go | 1 + routers/api/v2/deployment_logs.go | 6 +- routers/api/v2/gpu_group.go | 2 + routers/api/v2/gpu_lease.go | 6 + routers/api/v2/job.go | 4 + routers/api/v2/notification.go | 7 +- routers/api/v2/resource_migration.go | 8 +- routers/api/v2/sm.go | 10 +- routers/api/v2/snapshot.go | 5 + routers/api/v2/team.go | 10 +- routers/api/v2/user.go | 4 + routers/api/v2/vm.go | 10 +- routers/api/v2/vm_action.go | 1 + routers/api/v2/zone.go | 1 + 25 files changed, 3698 insertions(+), 7915 deletions(-) diff --git a/.gitignore b/.gitignore index f21f5e5a..0050e9a0 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,11 @@ cache/ # KubeConfig dir -kube/ \ No newline at end of file +kube/ + +# binary +go-deploy +go-deploy.exe + +# export package-lock.json +export/package-lock.json diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index ad3bc8e6..a94ad852 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -28,6 +28,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List deployments", @@ -101,6 +104,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Create deployment", @@ -152,6 +158,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get deployment", @@ -199,6 +208,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update deployment", @@ -255,6 +267,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete deployment", @@ -316,6 +331,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get CI config", @@ -365,6 +383,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Do command", @@ -432,6 +453,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get logs using Server-Sent Events", @@ -516,6 +540,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List GPU groups", @@ -585,6 +612,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get GPU group", @@ -646,6 +676,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List GPU leases", @@ -725,6 +758,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Create GPU lease", @@ -782,6 +818,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get GPU lease", @@ -841,6 +880,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update GPU lease", @@ -903,6 +945,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete GPU lease", @@ -1051,6 +1096,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List jobs", @@ -1120,6 +1168,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "GetJob job by id", @@ -1179,6 +1230,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update job. Only allowed for admins.", @@ -1254,6 +1308,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List notifications", @@ -1317,6 +1374,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get notification", @@ -1358,6 +1418,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update notification", @@ -1405,6 +1468,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete notification", @@ -1483,6 +1549,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List resource migrations", @@ -1544,6 +1613,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Create resource migration", @@ -1601,6 +1673,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get resource migration", @@ -1654,6 +1729,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update resource migration", @@ -1716,6 +1794,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete resource migration", @@ -1768,6 +1849,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List snapshots", @@ -1842,6 +1926,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Create snapshot", @@ -1892,49 +1979,14 @@ const docTemplateV2 = `{ } } }, - "/v2/status": { - "get": { - "description": "List of worker status", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Status" - ], - "summary": "List worker status", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.WorkerStatusRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, "/v2/storageManagers": { "get": { "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get storage manager list", @@ -2004,6 +2056,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete storage manager", @@ -2133,7 +2188,7 @@ const docTemplateV2 = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/body.TimestampedSystemCapacities" + "$ref": "#/definitions/body.TimestampedSystemStats" } } }, @@ -2179,7 +2234,7 @@ const docTemplateV2 = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/body.TimestampedSystemCapacities" + "$ref": "#/definitions/body.TimestampedSystemStatus" } } }, @@ -2203,6 +2258,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List teams", @@ -2270,6 +2328,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Create team", @@ -2321,6 +2382,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get team", @@ -2368,6 +2432,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update team", @@ -2424,6 +2491,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete team", @@ -2470,6 +2540,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List users", @@ -2545,6 +2618,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get user", @@ -2565,6 +2641,12 @@ const docTemplateV2 = `{ "name": "userId", "in": "path", "required": true + }, + { + "type": "boolean", + "description": "Discovery mode", + "name": "discover", + "in": "query" } ], "responses": { @@ -2592,6 +2674,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update user", @@ -2650,6 +2735,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Create API key", @@ -2708,6 +2796,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Creates a new action", @@ -2772,6 +2863,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List VMs", @@ -2851,6 +2945,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Create VM", @@ -2914,6 +3011,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get VM", @@ -2967,6 +3067,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Update VM", @@ -3035,6 +3138,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete VM", @@ -3096,6 +3202,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Get snapshot", @@ -3156,6 +3265,9 @@ const docTemplateV2 = `{ "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "Delete snapshot", @@ -3213,11 +3325,52 @@ const docTemplateV2 = `{ } } }, + "/v2/workerStatus": { + "get": { + "description": "List of worker status", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Status" + ], + "summary": "List worker status", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/body.WorkerStatusRead" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/sys.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/sys.ErrorResponse" + } + } + } + } + }, "/v2/zones": { "get": { "security": [ { "ApiKeyAuth": [] + }, + { + "KeycloakOAuth": [] } ], "description": "List zones", @@ -3326,6 +3479,34 @@ const docTemplateV2 = `{ } } }, + "body.ClusterCapacities": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "cpuCore": { + "$ref": "#/definitions/body.CpuCoreCapacities" + }, + "gpu": { + "$ref": "#/definitions/body.GpuCapacities" + }, + "ram": { + "$ref": "#/definitions/body.RamCapacities" + } + } + }, + "body.ClusterStats": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "podCount": { + "type": "integer" + } + } + }, "body.CpuCoreCapacities": { "type": "object", "properties": { @@ -3334,6 +3515,51 @@ const docTemplateV2 = `{ } } }, + "body.CpuStatus": { + "type": "object", + "properties": { + "load": { + "$ref": "#/definitions/body.CpuStatusLoad" + }, + "temp": { + "$ref": "#/definitions/body.CpuStatusTemp" + } + } + }, + "body.CpuStatusLoad": { + "type": "object", + "properties": { + "cores": { + "type": "array", + "items": { + "type": "integer" + } + }, + "main": { + "type": "number" + }, + "max": { + "type": "number" + } + } + }, + "body.CpuStatusTemp": { + "type": "object", + "properties": { + "cores": { + "type": "array", + "items": { + "type": "integer" + } + }, + "main": { + "type": "number" + }, + "max": { + "type": "number" + } + } + }, "body.CustomDomainRead": { "type": "object", "properties": { @@ -3419,6 +3645,7 @@ const docTemplateV2 = `{ "minLength": 3 }, "private": { + "description": "Deprecated: Use Visibility instead.", "type": "boolean" }, "ram": { @@ -3430,6 +3657,14 @@ const docTemplateV2 = `{ "maximum": 100, "minimum": 0 }, + "visibility": { + "type": "string", + "enum": [ + "public", + "private", + "auth" + ] + }, "volumes": { "type": "array", "maxItems": 100, @@ -3517,6 +3752,7 @@ const docTemplateV2 = `{ "type": "integer" }, "private": { + "description": "Deprecated: Use Visibility instead.", "type": "boolean" }, "repairedAt": { @@ -3552,6 +3788,9 @@ const docTemplateV2 = `{ "url": { "type": "string" }, + "visibility": { + "type": "string" + }, "volumes": { "type": "array", "items": { @@ -3631,6 +3870,7 @@ const docTemplateV2 = `{ "minLength": 3 }, "private": { + "description": "Deprecated: Use Visibility instead.", "type": "boolean" }, "ram": { @@ -3642,6 +3882,14 @@ const docTemplateV2 = `{ "maximum": 100, "minimum": 0 }, + "visibility": { + "type": "string", + "enum": [ + "public", + "private", + "auth" + ] + }, "volumes": { "type": "array", "maxItems": 100, @@ -3833,6 +4081,25 @@ const docTemplateV2 = `{ } } }, + "body.GpuStatus": { + "type": "object", + "properties": { + "temp": { + "type": "array", + "items": { + "$ref": "#/definitions/body.GpuStatusTemp" + } + } + } + }, + "body.GpuStatusTemp": { + "type": "object", + "properties": { + "main": { + "type": "number" + } + } + }, "body.HarborWebhook": { "type": "object", "properties": { @@ -3892,27 +4159,20 @@ const docTemplateV2 = `{ "body.HostCapacities": { "type": "object", "properties": { + "cpuCore": { + "$ref": "#/definitions/body.CpuCoreCapacities" + }, "displayName": { "type": "string" }, "gpu": { - "type": "object", - "properties": { - "count": { - "type": "integer" - } - } + "$ref": "#/definitions/body.GpuCapacities" }, "name": { "type": "string" }, "ram": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } + "$ref": "#/definitions/body.RamCapacities" }, "zone": { "description": "Zone is the name of the zone where the host is located.", @@ -3935,6 +4195,30 @@ const docTemplateV2 = `{ } } }, + "body.HostStatus": { + "type": "object", + "properties": { + "cpu": { + "$ref": "#/definitions/body.CpuStatus" + }, + "displayName": { + "type": "string" + }, + "gpu": { + "$ref": "#/definitions/body.GpuStatus" + }, + "name": { + "type": "string" + }, + "ram": { + "$ref": "#/definitions/body.RamStatus" + }, + "zone": { + "description": "Zone is the name of the zone where the host is located.", + "type": "string" + } + } + }, "body.HttpProxyCreate": { "type": "object", "required": [ @@ -3942,7 +4226,7 @@ const docTemplateV2 = `{ ], "properties": { "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a sub domain when confirming the domain.", + "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", "type": "string" }, "name": { @@ -3954,17 +4238,12 @@ const docTemplateV2 = `{ }, "body.HttpProxyRead": { "type": "object", - "required": [ - "name" - ], "properties": { "customDomain": { "$ref": "#/definitions/body.CustomDomainRead" }, "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 + "type": "string" }, "url": { "type": "string" @@ -3978,7 +4257,7 @@ const docTemplateV2 = `{ ], "properties": { "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a sub domain when confirming the domain.", + "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", "type": "string" }, "name": { @@ -4036,6 +4315,20 @@ const docTemplateV2 = `{ } } }, + "body.K8sStats": { + "type": "object", + "properties": { + "clusters": { + "type": "array", + "items": { + "$ref": "#/definitions/body.ClusterStats" + } + }, + "podCount": { + "type": "integer" + } + } + }, "body.NotificationRead": { "type": "object", "properties": { @@ -4055,6 +4348,9 @@ const docTemplateV2 = `{ "readAt": { "type": "string" }, + "toastedAt": { + "type": "string" + }, "type": { "type": "string" }, @@ -4068,6 +4364,9 @@ const docTemplateV2 = `{ "properties": { "read": { "type": "boolean" + }, + "toasted": { + "type": "boolean" } } }, @@ -4197,6 +4496,22 @@ const docTemplateV2 = `{ } } }, + "body.RamStatus": { + "type": "object", + "properties": { + "load": { + "$ref": "#/definitions/body.RamStatusLoad" + } + } + }, + "body.RamStatusLoad": { + "type": "object", + "properties": { + "main": { + "type": "number" + } + } + }, "body.ReplicaStatus": { "type": "object", "properties": { @@ -4461,13 +4776,26 @@ const docTemplateV2 = `{ "body.SystemCapacities": { "type": "object", "properties": { + "clusters": { + "description": "Per Cluster", + "type": "array", + "items": { + "$ref": "#/definitions/body.ClusterCapacities" + } + }, "cpuCore": { - "$ref": "#/definitions/body.CpuCoreCapacities" + "description": "Total", + "allOf": [ + { + "$ref": "#/definitions/body.CpuCoreCapacities" + } + ] }, "gpu": { "$ref": "#/definitions/body.GpuCapacities" }, "hosts": { + "description": "Per Host", "type": "array", "items": { "$ref": "#/definitions/body.HostCapacities" @@ -4478,6 +4806,25 @@ const docTemplateV2 = `{ } } }, + "body.SystemStats": { + "type": "object", + "properties": { + "k8s": { + "$ref": "#/definitions/body.K8sStats" + } + } + }, + "body.SystemStatus": { + "type": "object", + "properties": { + "hosts": { + "type": "array", + "items": { + "$ref": "#/definitions/body.HostStatus" + } + } + } + }, "body.TeamCreate": { "type": "object", "required": [ @@ -4666,6 +5013,28 @@ const docTemplateV2 = `{ } } }, + "body.TimestampedSystemStats": { + "type": "object", + "properties": { + "stats": { + "$ref": "#/definitions/body.SystemStats" + }, + "timestamp": { + "type": "string" + } + } + }, + "body.TimestampedSystemStatus": { + "type": "object", + "properties": { + "status": { + "$ref": "#/definitions/body.SystemStatus" + }, + "timestamp": { + "type": "string" + } + } + }, "body.Usage": { "type": "object", "properties": { @@ -5034,15 +5403,10 @@ const docTemplateV2 = `{ "minimum": 1 }, "name": { - "description": "Name is used to rename a VM.\nIf specified, only name will be updated.", "type": "string", "maxLength": 30, "minLength": 3 }, - "ownerId": { - "description": "OwnerID is used to initiate transfer a VM to another user.\nIf specified, only the transfer will happen.\nIf specified but empty, the transfer will be canceled.", - "type": "string" - }, "ports": { "type": "array", "maxItems": 10, @@ -5178,6 +5542,17 @@ const docTemplateV2 = `{ "type": "apiKey", "name": "X-Api-Key", "in": "header" + }, + "KeycloakOAuth": { + "type": "oauth2", + "flow": "accessCode", + "authorizationUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth", + "tokenUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token", + "scopes": { + "email": "email", + "openid": "openid", + "profile": "profile" + } } } }` diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index b690ef2d..cd0954a7 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -1,5175 +1 @@ -{ - "swagger": "2.0", - "info": { - "description": "This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.", - "title": "go-deploy API", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "name": "Support", - "url": "https://github.com/kthcloud/go-deploy" - }, - "license": { - "name": "MIT License", - "url": "https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme" - }, - "version": "1.0" - }, - "paths": { - "/v2/deployments": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List deployments", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "List deployments", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "boolean", - "description": "Include shared", - "name": "shared", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.DeploymentRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Create deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Create deployment", - "parameters": [ - { - "description": "Deployment body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.DeploymentCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Get deployment", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Update deployment", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - }, - { - "description": "Deployment update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.DeploymentUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Delete deployment", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}/ciConfig": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get CI config", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Get CI config", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.CiConfig" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}/command": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Do command", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Do command", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - }, - { - "description": "Command body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.DeploymentCommand" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}/logs": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get logs using Server-Sent Events", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Get logs using Server-Sent Events", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/discover": { - "get": { - "description": "Discover", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Discover" - ], - "summary": "Discover", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DiscoverRead" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuGroups": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List GPU groups", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuGroup" - ], - "summary": "List GPU groups", - "parameters": [ - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.GpuGroupRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuGroups/{gpuGroupId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get GPU group", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuGroup" - ], - "summary": "Get GPU group", - "parameters": [ - { - "type": "string", - "description": "GPU group ID", - "name": "gpuGroupId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuGroupRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuLeases": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List GPU leases", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "List GPU leases", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by VM ID", - "name": "vmId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.GpuLeaseRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Create GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Create GPU Lease", - "parameters": [ - { - "description": "GPU lease", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.GpuLeaseCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuLeases/{gpuLeaseId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Get GPU lease", - "parameters": [ - { - "type": "string", - "description": "GPU lease ID", - "name": "gpuLeaseId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Update GPU lease", - "parameters": [ - { - "type": "string", - "description": "GPU lease ID", - "name": "gpuLeaseId", - "in": "path", - "required": true - }, - { - "description": "GPU lease", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.GpuLeaseUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Delete GPU lease", - "parameters": [ - { - "type": "string", - "description": "GPU lease ID", - "name": "gpuLeaseId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/hooks/harbor": { - "post": { - "description": "Handle Harbor hook", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Handle Harbor hook", - "parameters": [ - { - "type": "string", - "description": "Basic auth token", - "name": "Authorization", - "in": "header" - }, - { - "description": "Harbor webhook body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.HarborWebhook" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/hosts": { - "get": { - "description": "List Hosts", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Host" - ], - "summary": "List Hosts", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.HostRead" - } - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/jobs": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List jobs", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Job" - ], - "summary": "List jobs", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "string", - "description": "Filter by type", - "name": "type", - "in": "query" - }, - { - "type": "string", - "description": "Filter by status", - "name": "status", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.JobRead" - } - } - } - } - } - }, - "/v2/jobs/{jobId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "GetJob job by id", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Job" - ], - "summary": "GetJob job by id", - "parameters": [ - { - "type": "string", - "description": "Job ID", - "name": "jobId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.JobRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update job. Only allowed for admins.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Job" - ], - "summary": "Update job", - "parameters": [ - { - "type": "string", - "description": "Job ID", - "name": "jobId", - "in": "path", - "required": true - }, - { - "description": "Job update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.JobUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.JobRead" - } - } - } - } - }, - "/v2/metrics": { - "get": { - "description": "Get metrics", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Get metrics", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/notifications": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List notifications", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "List notifications", - "parameters": [ - { - "type": "boolean", - "description": "List all notifications", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.NotificationRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/notifications/{notificationId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get notification", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "Get notification", - "parameters": [ - { - "type": "string", - "description": "Notification ID", - "name": "notificationId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.NotificationRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update notification", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "Update notification", - "parameters": [ - { - "type": "string", - "description": "Notification ID", - "name": "notificationId", - "in": "path", - "required": true - }, - { - "description": "Notification update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.NotificationUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete notification", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "Delete notification", - "parameters": [ - { - "type": "string", - "description": "Notification ID", - "name": "notificationId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/register": { - "get": { - "description": "Register resource", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Register" - ], - "summary": "Register resource", - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/resourceMigrations": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List resource migrations", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "List resource migrations", - "parameters": [ - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.ResourceMigrationRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Create resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Create resource migration", - "parameters": [ - { - "description": "Resource Migration Create", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.ResourceMigrationCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ResourceMigrationCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/resourceMigrations/{resourceMigrationId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Get resource migration", - "parameters": [ - { - "type": "string", - "description": "Resource Migration ID", - "name": "resourceMigrationId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ResourceMigrationRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Update resource migration", - "parameters": [ - { - "type": "string", - "description": "Resource Migration ID", - "name": "resourceMigrationId", - "in": "path", - "required": true - }, - { - "description": "Resource Migration Update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.ResourceMigrationUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ResourceMigrationUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Delete resource migration", - "parameters": [ - { - "type": "string", - "description": "Resource Migration ID", - "name": "resourceMigrationId", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/snapshots": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List snapshots", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "List snapshots", - "parameters": [ - { - "type": "string", - "description": "Filter by VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.VmSnapshotRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Create snapshot", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "Create snapshot", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmSnapshotCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/status": { - "get": { - "description": "List of worker status", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Status" - ], - "summary": "List worker status", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.WorkerStatusRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/storageManagers": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get storage manager list", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "StorageManager" - ], - "summary": "Get storage manager list", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.SmRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/storageManagers/{storageManagerId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete storage manager", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "StorageManager" - ], - "summary": "Delete storage manager", - "parameters": [ - { - "type": "string", - "description": "Storage manager ID", - "name": "storageManagerId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.SmDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/systemCapacities": { - "get": { - "description": "List system capacities", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "System" - ], - "summary": "List system capacities", - "parameters": [ - { - "type": "integer", - "description": "n", - "name": "n", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TimestampedSystemCapacities" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/systemStats": { - "get": { - "description": "List system stats", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "System" - ], - "summary": "List system stats", - "parameters": [ - { - "type": "integer", - "description": "n", - "name": "n", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TimestampedSystemCapacities" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/systemStatus": { - "get": { - "description": "List system stats", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "System" - ], - "summary": "List system stats", - "parameters": [ - { - "type": "integer", - "description": "n", - "name": "n", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TimestampedSystemCapacities" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/teams": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List teams", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "List teams", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TeamRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Create team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Create team", - "parameters": [ - { - "description": "Team", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.TeamCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.TeamRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/teams/{teamId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Get team", - "parameters": [ - { - "type": "string", - "description": "Team ID", - "name": "teamId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.TeamRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Update team", - "parameters": [ - { - "type": "string", - "description": "Team ID", - "name": "teamId", - "in": "path", - "required": true - }, - { - "description": "Team", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.TeamUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.TeamRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Delete team", - "parameters": [ - { - "type": "string", - "description": "Team ID", - "name": "teamId", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/users": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List users", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "List users", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "boolean", - "description": "Discovery mode", - "name": "discover", - "in": "query" - }, - { - "type": "string", - "description": "Search query", - "name": "search", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.UserRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/users/{userId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get user", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "Get user", - "parameters": [ - { - "type": "string", - "description": "User ID", - "name": "userId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.UserRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update user", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "Update user", - "parameters": [ - { - "type": "string", - "description": "User ID", - "name": "userId", - "in": "path", - "required": true - }, - { - "description": "User update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.UserUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.UserRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/users/{userId}/apiKeys": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Create API key", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "Create API key", - "parameters": [ - { - "type": "string", - "description": "User ID", - "name": "userId", - "in": "path", - "required": true - }, - { - "description": "API key create body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.ApiKeyCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ApiKeyCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vmActions": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Creates a new action", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VmAction" - ], - "summary": "Creates a new action", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "description": "actions body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.VmActionCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmActionCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vms": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List VMs", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "List VMs", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.VmRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Create VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Create VM", - "parameters": [ - { - "description": "VM body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.VmCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vms/{vmId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Get VM", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Update VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Update VM", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "description": "VM update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.VmUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Delete VM", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vms/{vmId}/snapshot/{snapshotId}": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Get snapshot", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "Get snapshot", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Snapshot ID", - "name": "snapshotId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmSnapshotRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "Delete snapshot", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "Delete snapshot", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Snapshot ID", - "name": "snapshotId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmSnapshotDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/zones": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "List zones", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Zone" - ], - "summary": "List zones", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.ZoneRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - } - }, - "definitions": { - "body.ApiKey": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "expiresAt": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "body.ApiKeyCreate": { - "type": "object", - "required": [ - "expiresAt", - "name" - ], - "properties": { - "expiresAt": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "body.ApiKeyCreated": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "expiresAt": { - "type": "string" - }, - "key": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "body.BindingError": { - "type": "object", - "properties": { - "validationErrors": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "body.CiConfig": { - "type": "object", - "properties": { - "config": { - "type": "string" - } - } - }, - "body.CpuCoreCapacities": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } - }, - "body.CustomDomainRead": { - "type": "object", - "properties": { - "domain": { - "type": "string" - }, - "secret": { - "type": "string" - }, - "status": { - "type": "string" - }, - "url": { - "type": "string" - } - } - }, - "body.DeploymentCommand": { - "type": "object", - "required": [ - "command" - ], - "properties": { - "command": { - "type": "string", - "enum": [ - "restart" - ] - } - } - }, - "body.DeploymentCreate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "args": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "cpuCores": { - "type": "number", - "minimum": 0.1 - }, - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "envs": { - "type": "array", - "maxItems": 1000, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Env" - } - }, - "healthCheckPath": { - "type": "string", - "maxLength": 1000, - "minLength": 0 - }, - "image": { - "type": "string", - "maxLength": 1000, - "minLength": 1 - }, - "initCommands": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "private": { - "type": "boolean" - }, - "ram": { - "type": "number", - "minimum": 0.1 - }, - "replicas": { - "type": "integer", - "maximum": 100, - "minimum": 0 - }, - "volumes": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Volume" - } - }, - "zone": { - "description": "Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.", - "type": "string" - } - } - }, - "body.DeploymentCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.DeploymentRead": { - "type": "object", - "properties": { - "accessedAt": { - "type": "string" - }, - "args": { - "type": "array", - "items": { - "type": "string" - } - }, - "createdAt": { - "type": "string" - }, - "customDomain": { - "$ref": "#/definitions/body.CustomDomainRead" - }, - "envs": { - "type": "array", - "items": { - "$ref": "#/definitions/body.Env" - } - }, - "error": { - "type": "string" - }, - "healthCheckPath": { - "type": "string" - }, - "id": { - "type": "string" - }, - "image": { - "type": "string" - }, - "initCommands": { - "type": "array", - "items": { - "type": "string" - } - }, - "integrations": { - "description": "Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub", - "type": "array", - "items": { - "type": "string" - } - }, - "internalPort": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "pingResult": { - "type": "integer" - }, - "private": { - "type": "boolean" - }, - "repairedAt": { - "type": "string" - }, - "replicaStatus": { - "$ref": "#/definitions/body.ReplicaStatus" - }, - "restartedAt": { - "type": "string" - }, - "specs": { - "$ref": "#/definitions/body.DeploymentSpecs" - }, - "status": { - "type": "string" - }, - "storageUrl": { - "type": "string" - }, - "teams": { - "type": "array", - "items": { - "type": "string" - } - }, - "type": { - "type": "string" - }, - "updatedAt": { - "type": "string" - }, - "url": { - "type": "string" - }, - "volumes": { - "type": "array", - "items": { - "$ref": "#/definitions/body.Volume" - } - }, - "zone": { - "type": "string" - } - } - }, - "body.DeploymentSpecs": { - "type": "object", - "properties": { - "cpuCores": { - "type": "number" - }, - "ram": { - "type": "number" - }, - "replicas": { - "type": "integer" - } - } - }, - "body.DeploymentUpdate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "args": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "cpuCores": { - "type": "number", - "minimum": 0.1 - }, - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "envs": { - "type": "array", - "maxItems": 1000, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Env" - } - }, - "healthCheckPath": { - "type": "string", - "maxLength": 1000, - "minLength": 0 - }, - "image": { - "type": "string", - "maxLength": 1000, - "minLength": 1 - }, - "initCommands": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "private": { - "type": "boolean" - }, - "ram": { - "type": "number", - "minimum": 0.1 - }, - "replicas": { - "type": "integer", - "maximum": 100, - "minimum": 0 - }, - "volumes": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Volume" - } - } - } - }, - "body.DeploymentUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.DiscoverRead": { - "type": "object", - "properties": { - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/body.Role" - } - }, - "version": { - "type": "string" - } - } - }, - "body.Env": { - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "value": { - "type": "string", - "maxLength": 10000, - "minLength": 1 - } - } - }, - "body.GpuCapacities": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } - }, - "body.GpuGroupRead": { - "type": "object", - "properties": { - "available": { - "type": "integer" - }, - "displayName": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "total": { - "type": "integer" - }, - "vendor": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.GpuLeaseCreate": { - "type": "object", - "required": [ - "gpuGroupId" - ], - "properties": { - "gpuGroupId": { - "description": "GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.", - "type": "string" - }, - "leaseForever": { - "description": "LeaseForever is used to specify whether the lease should be created forever.", - "type": "boolean" - } - } - }, - "body.GpuLeaseCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.GpuLeaseDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.GpuLeaseRead": { - "type": "object", - "properties": { - "activatedAt": { - "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", - "type": "string" - }, - "active": { - "type": "boolean" - }, - "assignedAt": { - "description": "AssignedAt specifies the time when the lease was assigned to the user.", - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "expiredAt": { - "type": "string" - }, - "expiresAt": { - "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", - "type": "string" - }, - "gpuGroupId": { - "type": "string" - }, - "id": { - "type": "string" - }, - "leaseDuration": { - "type": "number" - }, - "queuePosition": { - "type": "integer" - }, - "userId": { - "type": "string" - }, - "vmId": { - "description": "VmID is set when the lease is attached to a VM.", - "type": "string" - } - } - }, - "body.GpuLeaseUpdate": { - "type": "object", - "properties": { - "vmId": { - "description": "VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.", - "type": "string" - } - } - }, - "body.GpuLeaseUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.HarborWebhook": { - "type": "object", - "properties": { - "event_data": { - "type": "object", - "properties": { - "repository": { - "type": "object", - "properties": { - "date_created": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "namespace": { - "type": "string" - }, - "repo_full_name": { - "type": "string" - }, - "repo_type": { - "type": "string" - } - } - }, - "resources": { - "type": "array", - "items": { - "type": "object", - "properties": { - "digest": { - "type": "string" - }, - "resource_url": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - } - } - } - }, - "occur_at": { - "type": "integer" - }, - "operator": { - "type": "string" - }, - "type": { - "type": "string" - } - } - }, - "body.HostCapacities": { - "type": "object", - "properties": { - "displayName": { - "type": "string" - }, - "gpu": { - "type": "object", - "properties": { - "count": { - "type": "integer" - } - } - }, - "name": { - "type": "string" - }, - "ram": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } - }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - } - }, - "body.HostRead": { - "type": "object", - "properties": { - "displayName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - } - }, - "body.HttpProxyCreate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a sub domain when confirming the domain.", - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - } - } - }, - "body.HttpProxyRead": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "customDomain": { - "$ref": "#/definitions/body.CustomDomainRead" - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "url": { - "type": "string" - } - } - }, - "body.HttpProxyUpdate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a sub domain when confirming the domain.", - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - } - } - }, - "body.JobRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "finishedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "lastError": { - "type": "string" - }, - "lastRunAt": { - "type": "string" - }, - "runAfter": { - "type": "string" - }, - "status": { - "type": "string" - }, - "type": { - "type": "string" - }, - "userId": { - "type": "string" - } - } - }, - "body.JobUpdate": { - "type": "object", - "properties": { - "status": { - "type": "string", - "enum": [ - "pending", - "running", - "failed", - "terminated", - "finished", - "completed" - ] - } - } - }, - "body.NotificationRead": { - "type": "object", - "properties": { - "completedAt": { - "type": "string" - }, - "content": { - "type": "object", - "additionalProperties": true - }, - "createdAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "readAt": { - "type": "string" - }, - "type": { - "type": "string" - }, - "userId": { - "type": "string" - } - } - }, - "body.NotificationUpdate": { - "type": "object", - "properties": { - "read": { - "type": "boolean" - } - } - }, - "body.PortCreate": { - "type": "object", - "required": [ - "name", - "port", - "protocol" - ], - "properties": { - "httpProxy": { - "$ref": "#/definitions/body.HttpProxyCreate" - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "port": { - "type": "integer", - "maximum": 65535, - "minimum": 1 - }, - "protocol": { - "type": "string", - "enum": [ - "tcp", - "udp" - ] - } - } - }, - "body.PortRead": { - "type": "object", - "properties": { - "externalPort": { - "type": "integer" - }, - "httpProxy": { - "$ref": "#/definitions/body.HttpProxyRead" - }, - "name": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "protocol": { - "type": "string" - } - } - }, - "body.PortUpdate": { - "type": "object", - "required": [ - "name", - "port", - "protocol" - ], - "properties": { - "httpProxy": { - "$ref": "#/definitions/body.HttpProxyUpdate" - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "port": { - "type": "integer", - "maximum": 65535, - "minimum": 1 - }, - "protocol": { - "type": "string", - "enum": [ - "tcp", - "udp" - ] - } - } - }, - "body.PublicKey": { - "type": "object", - "required": [ - "key", - "name" - ], - "properties": { - "key": { - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 1 - } - } - }, - "body.Quota": { - "type": "object", - "properties": { - "cpuCores": { - "type": "number" - }, - "diskSize": { - "type": "number" - }, - "gpuLeaseDuration": { - "description": "in hours", - "type": "number" - }, - "ram": { - "type": "number" - }, - "snapshots": { - "type": "integer" - } - } - }, - "body.RamCapacities": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } - }, - "body.ReplicaStatus": { - "type": "object", - "properties": { - "availableReplicas": { - "description": "AvailableReplicas is the number of replicas that are available.", - "type": "integer" - }, - "desiredReplicas": { - "description": "DesiredReplicas is the number of replicas that the deployment should have.", - "type": "integer" - }, - "readyReplicas": { - "description": "ReadyReplicas is the number of replicas that are ready.", - "type": "integer" - }, - "unavailableReplicas": { - "description": "UnavailableReplicas is the number of replicas that are unavailable.", - "type": "integer" - } - } - }, - "body.ResourceMigrationCreate": { - "type": "object", - "required": [ - "resourceId", - "type" - ], - "properties": { - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string", - "enum": [ - "updateOwner" - ] - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.", - "type": "object", - "required": [ - "ownerId" - ], - "properties": { - "ownerId": { - "type": "string" - } - } - } - } - }, - "body.ResourceMigrationCreated": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "deletedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "jobId": { - "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.", - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "type": "object", - "properties": { - "ownerId": { - "type": "string" - } - } - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - } - }, - "body.ResourceMigrationRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "deletedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "type": "object", - "properties": { - "ownerId": { - "type": "string" - } - } - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - } - }, - "body.ResourceMigrationUpdate": { - "type": "object", - "required": [ - "status" - ], - "properties": { - "code": { - "description": "Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending", - "type": "string" - } - } - }, - "body.ResourceMigrationUpdated": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "deletedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "jobId": { - "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.", - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "type": "object", - "properties": { - "ownerId": { - "type": "string" - } - } - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - } - }, - "body.Role": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "permissions": { - "type": "array", - "items": { - "type": "string" - } - }, - "quota": { - "$ref": "#/definitions/body.Quota" - } - } - }, - "body.SmDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.SmRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "url": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.SystemCapacities": { - "type": "object", - "properties": { - "cpuCore": { - "$ref": "#/definitions/body.CpuCoreCapacities" - }, - "gpu": { - "$ref": "#/definitions/body.GpuCapacities" - }, - "hosts": { - "type": "array", - "items": { - "$ref": "#/definitions/body.HostCapacities" - } - }, - "ram": { - "$ref": "#/definitions/body.RamCapacities" - } - } - }, - "body.TeamCreate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "description": { - "type": "string", - "maxLength": 1000 - }, - "members": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.TeamMemberCreate" - } - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "resources": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - } - } - }, - "body.TeamMember": { - "type": "object", - "properties": { - "addedAt": { - "type": "string" - }, - "email": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "gravatarUrl": { - "type": "string" - }, - "id": { - "type": "string" - }, - "joinedAt": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "memberStatus": { - "type": "string" - }, - "teamRole": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "body.TeamMemberCreate": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - }, - "teamRole": { - "description": "default to MemberRoleAdmin right now", - "type": "string" - } - } - }, - "body.TeamMemberUpdate": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - }, - "teamRole": { - "description": "default to MemberRoleAdmin right now", - "type": "string" - } - } - }, - "body.TeamRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string" - }, - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TeamMember" - } - }, - "name": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "resources": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TeamResource" - } - }, - "updatedAt": { - "type": "string" - } - } - }, - "body.TeamResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - } - }, - "body.TeamUpdate": { - "type": "object", - "properties": { - "description": { - "type": "string", - "maxLength": 1000 - }, - "members": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.TeamMemberUpdate" - } - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "resources": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - } - } - }, - "body.TimestampedSystemCapacities": { - "type": "object", - "properties": { - "capacities": { - "$ref": "#/definitions/body.SystemCapacities" - }, - "timestamp": { - "type": "string" - } - } - }, - "body.Usage": { - "type": "object", - "properties": { - "cpuCores": { - "type": "number" - }, - "diskSize": { - "type": "integer" - }, - "ram": { - "type": "number" - } - } - }, - "body.UserData": { - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "type": "string", - "maxLength": 255, - "minLength": 1 - }, - "value": { - "type": "string", - "maxLength": 255, - "minLength": 1 - } - } - }, - "body.UserRead": { - "type": "object", - "properties": { - "admin": { - "type": "boolean" - }, - "apiKeys": { - "type": "array", - "items": { - "$ref": "#/definitions/body.ApiKey" - } - }, - "email": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "gravatarUrl": { - "type": "string" - }, - "id": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "publicKeys": { - "type": "array", - "items": { - "$ref": "#/definitions/body.PublicKey" - } - }, - "quota": { - "$ref": "#/definitions/body.Quota" - }, - "role": { - "$ref": "#/definitions/body.Role" - }, - "storageUrl": { - "type": "string" - }, - "usage": { - "$ref": "#/definitions/body.Usage" - }, - "userData": { - "type": "array", - "items": { - "$ref": "#/definitions/body.UserData" - } - }, - "username": { - "type": "string" - } - } - }, - "body.UserUpdate": { - "type": "object", - "properties": { - "apiKeys": { - "description": "ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.", - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.ApiKey" - } - }, - "publicKeys": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.PublicKey" - } - }, - "userData": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.UserData" - } - } - } - }, - "body.VmActionCreate": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string", - "enum": [ - "start", - "stop", - "restart", - "repair" - ] - } - } - }, - "body.VmActionCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmCreate": { - "type": "object", - "required": [ - "cpuCores", - "diskSize", - "name", - "ram", - "sshPublicKey" - ], - "properties": { - "cpuCores": { - "type": "integer", - "minimum": 1 - }, - "diskSize": { - "type": "integer", - "minimum": 10 - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "ports": { - "type": "array", - "maxItems": 10, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.PortCreate" - } - }, - "ram": { - "type": "integer", - "minimum": 1 - }, - "sshPublicKey": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.VmCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmGpuLease": { - "type": "object", - "properties": { - "activatedAt": { - "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", - "type": "string" - }, - "assignedAt": { - "description": "AssignedAt specifies the time when the lease was assigned to the user.", - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "expiredAt": { - "description": "ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.", - "type": "string" - }, - "expiresAt": { - "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", - "type": "string" - }, - "gpuGroupId": { - "type": "string" - }, - "id": { - "type": "string" - }, - "leaseDuration": { - "type": "number" - } - } - }, - "body.VmRead": { - "type": "object", - "properties": { - "accessedAt": { - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "gpu": { - "$ref": "#/definitions/body.VmGpuLease" - }, - "host": { - "type": "string" - }, - "id": { - "type": "string" - }, - "internalName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "ports": { - "type": "array", - "items": { - "$ref": "#/definitions/body.PortRead" - } - }, - "repairedAt": { - "type": "string" - }, - "specs": { - "$ref": "#/definitions/body.VmSpecs" - }, - "sshConnectionString": { - "type": "string" - }, - "sshPublicKey": { - "type": "string" - }, - "status": { - "type": "string" - }, - "teams": { - "type": "array", - "items": { - "type": "string" - } - }, - "updatedAt": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.VmSnapshotCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmSnapshotDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmSnapshotRead": { - "type": "object", - "properties": { - "created": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "status": { - "type": "string" - } - } - }, - "body.VmSpecs": { - "type": "object", - "properties": { - "cpuCores": { - "type": "integer" - }, - "diskSize": { - "type": "integer" - }, - "ram": { - "type": "integer" - } - } - }, - "body.VmUpdate": { - "type": "object", - "properties": { - "cpuCores": { - "type": "integer", - "minimum": 1 - }, - "name": { - "description": "Name is used to rename a VM.\nIf specified, only name will be updated.", - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "ownerId": { - "description": "OwnerID is used to initiate transfer a VM to another user.\nIf specified, only the transfer will happen.\nIf specified but empty, the transfer will be canceled.", - "type": "string" - }, - "ports": { - "type": "array", - "maxItems": 10, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.PortUpdate" - } - }, - "ram": { - "type": "integer", - "minimum": 1 - } - } - }, - "body.VmUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.Volume": { - "type": "object", - "required": [ - "appPath", - "name", - "serverPath" - ], - "properties": { - "appPath": { - "type": "string", - "maxLength": 255, - "minLength": 1 - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "serverPath": { - "type": "string", - "maxLength": 255, - "minLength": 1 - } - } - }, - "body.WorkerStatusRead": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "reportedAt": { - "type": "string" - }, - "status": { - "type": "string" - } - } - }, - "body.ZoneEndpoints": { - "type": "object", - "properties": { - "deployment": { - "type": "string" - }, - "storage": { - "type": "string" - }, - "vm": { - "type": "string" - }, - "vmApp": { - "type": "string" - } - } - }, - "body.ZoneRead": { - "type": "object", - "properties": { - "capabilities": { - "type": "array", - "items": { - "type": "string" - } - }, - "description": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "endpoints": { - "$ref": "#/definitions/body.ZoneEndpoints" - }, - "legacy": { - "type": "boolean" - }, - "name": { - "type": "string" - } - } - }, - "sys.Error": { - "type": "object", - "properties": { - "code": { - "type": "string" - }, - "msg": { - "type": "string" - } - } - }, - "sys.ErrorResponse": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/definitions/sys.Error" - } - } - } - } - }, - "securityDefinitions": { - "ApiKeyAuth": { - "type": "apiKey", - "name": "X-Api-Key", - "in": "header" - } - } -} \ No newline at end of file +{"openapi":"3.0.1","info":{"title":"go-deploy API","description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","termsOfService":"http://swagger.io/terms/","contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"version":"1.0"},"servers":[{"url":"/"}],"paths":{"/v2/deployments":{"get":{"tags":["Deployment"],"summary":"List deployments","description":"List deployments","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"shared","in":"query","description":"Include shared","schema":{"type":"boolean"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.DeploymentRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Deployment"],"summary":"Create deployment","description":"Create deployment","requestBody":{"description":"Deployment body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/deployments/{deploymentId}":{"get":{"tags":["Deployment"],"summary":"Get deployment","description":"Get deployment","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Deployment"],"summary":"Update deployment","description":"Update deployment","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Deployment update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["Deployment"],"summary":"Delete deployment","description":"Delete deployment","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"tags":["Deployment"],"summary":"Get CI config","description":"Get CI config","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/deployments/{deploymentId}/command":{"post":{"tags":["Deployment"],"summary":"Do command","description":"Do command","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Command body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"required":true},"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/deployments/{deploymentId}/logs":{"get":{"tags":["Deployment"],"summary":"Get logs using Server-Sent Events","description":"Get logs using Server-Sent Events","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/discover":{"get":{"tags":["Discover"],"summary":"Discover","description":"Discover","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/gpuGroups":{"get":{"tags":["GpuGroup"],"summary":"List GPU groups","description":"List GPU groups","parameters":[{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.GpuGroupRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"tags":["GpuGroup"],"summary":"Get GPU group","description":"Get GPU group","parameters":[{"name":"gpuGroupId","in":"path","description":"GPU group ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/gpuLeases":{"get":{"tags":["GpuLease"],"summary":"List GPU leases","description":"List GPU leases","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"vmId","in":"query","description":"Filter by VM ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["GpuLease"],"summary":"Create GPU Lease","description":"Create GPU lease","requestBody":{"description":"GPU lease","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/gpuLeases/{gpuLeaseId}":{"get":{"tags":["GpuLease"],"summary":"Get GPU lease","description":"Get GPU lease","parameters":[{"name":"gpuLeaseId","in":"path","description":"GPU lease ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["GpuLease"],"summary":"Update GPU lease","description":"Update GPU lease","parameters":[{"name":"gpuLeaseId","in":"path","description":"GPU lease ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"GPU lease","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["GpuLease"],"summary":"Delete GPU lease","description":"Delete GPU lease","parameters":[{"name":"gpuLeaseId","in":"path","description":"GPU lease ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/hooks/harbor":{"post":{"tags":["Deployment"],"summary":"Handle Harbor hook","description":"Handle Harbor hook","parameters":[{"name":"Authorization","in":"header","description":"Basic auth token","schema":{"type":"string"}}],"requestBody":{"description":"Harbor webhook body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"required":true},"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"x-codegen-request-body-name":"body"}},"/v2/hosts":{"get":{"tags":["Host"],"summary":"List Hosts","description":"List Hosts","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.HostRead"}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/jobs":{"get":{"tags":["Job"],"summary":"List jobs","description":"List jobs","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"type","in":"query","description":"Filter by type","schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by status","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.JobRead"}}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/jobs/{jobId}":{"get":{"tags":["Job"],"summary":"GetJob job by id","description":"GetJob job by id","parameters":[{"name":"jobId","in":"path","description":"Job ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Job"],"summary":"Update job","description":"Update job. Only allowed for admins.","parameters":[{"name":"jobId","in":"path","description":"Job ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Job update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/metrics":{"get":{"tags":["Metrics"],"summary":"Get metrics","description":"Get metrics","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/notifications":{"get":{"tags":["Notification"],"summary":"List notifications","description":"List notifications","parameters":[{"name":"all","in":"query","description":"List all notifications","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.NotificationRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/notifications/{notificationId}":{"get":{"tags":["Notification"],"summary":"Get notification","description":"Get notification","parameters":[{"name":"notificationId","in":"path","description":"Notification ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Notification"],"summary":"Update notification","description":"Update notification","parameters":[{"name":"notificationId","in":"path","description":"Notification ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Notification update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["Notification"],"summary":"Delete notification","description":"Delete notification","parameters":[{"name":"notificationId","in":"path","description":"Notification ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/register":{"get":{"tags":["Register"],"summary":"Register resource","description":"Register resource","responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/resourceMigrations":{"get":{"tags":["ResourceMigration"],"summary":"List resource migrations","description":"List resource migrations","parameters":[{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["ResourceMigration"],"summary":"Create resource migration","description":"Create resource migration","requestBody":{"description":"Resource Migration Create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/resourceMigrations/{resourceMigrationId}":{"get":{"tags":["ResourceMigration"],"summary":"Get resource migration","description":"Get resource migration","parameters":[{"name":"resourceMigrationId","in":"path","description":"Resource Migration ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["ResourceMigration"],"summary":"Update resource migration","description":"Update resource migration","parameters":[{"name":"resourceMigrationId","in":"path","description":"Resource Migration ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Resource Migration Update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["ResourceMigration"],"summary":"Delete resource migration","description":"Delete resource migration","parameters":[{"name":"resourceMigrationId","in":"path","description":"Resource Migration ID","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/snapshots":{"get":{"tags":["Snapshot"],"summary":"List snapshots","description":"List snapshots","parameters":[{"name":"vmId","in":"path","description":"Filter by VM ID","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Snapshot"],"summary":"Create snapshot","description":"Create snapshot","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/storageManagers":{"get":{"tags":["StorageManager"],"summary":"Get storage manager list","description":"Get storage manager list","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.SmRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/storageManagers/{storageManagerId}":{"get":{"tags":["StorageManager"],"summary":"Delete storage manager","description":"Delete storage manager","parameters":[{"name":"storageManagerId","in":"path","description":"Storage manager ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/systemCapacities":{"get":{"tags":["System"],"summary":"List system capacities","description":"List system capacities","parameters":[{"name":"n","in":"query","description":"n","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/systemStats":{"get":{"tags":["System"],"summary":"List system stats","description":"List system stats","parameters":[{"name":"n","in":"query","description":"n","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/systemStatus":{"get":{"tags":["System"],"summary":"List system stats","description":"List system stats","parameters":[{"name":"n","in":"query","description":"n","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/teams":{"get":{"tags":["Team"],"summary":"List teams","description":"List teams","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TeamRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Team"],"summary":"Create team","description":"Create team","requestBody":{"description":"Team","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/teams/{teamId}":{"get":{"tags":["Team"],"summary":"Get team","description":"Get team","parameters":[{"name":"teamId","in":"path","description":"Team ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Team"],"summary":"Update team","description":"Update team","parameters":[{"name":"teamId","in":"path","description":"Team ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Team","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["Team"],"summary":"Delete team","description":"Delete team","parameters":[{"name":"teamId","in":"path","description":"Team ID","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/users":{"get":{"tags":["User"],"summary":"List users","description":"List users","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"discover","in":"query","description":"Discovery mode","schema":{"type":"boolean"}},{"name":"search","in":"query","description":"Search query","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.UserRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/users/{userId}":{"get":{"tags":["User"],"summary":"Get user","description":"Get user","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string"}},{"name":"discover","in":"query","description":"Discovery mode","schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["User"],"summary":"Update user","description":"Update user","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"User update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/users/{userId}/apiKeys":{"post":{"tags":["User"],"summary":"Create API key","description":"Create API key","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"API key create body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/vmActions":{"post":{"tags":["VmAction"],"summary":"Creates a new action","description":"Creates a new action","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"actions body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/vms":{"get":{"tags":["VM"],"summary":"List VMs","description":"List VMs","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.VmRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["VM"],"summary":"Create VM","description":"Create VM","requestBody":{"description":"VM body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/vms/{vmId}":{"get":{"tags":["VM"],"summary":"Get VM","description":"Get VM","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["VM"],"summary":"Update VM","description":"Update VM","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"VM update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["VM"],"summary":"Delete VM","description":"Delete VM","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"post":{"tags":["Snapshot"],"summary":"Get snapshot","description":"Get snapshot","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}},{"name":"snapshotId","in":"path","description":"Snapshot ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"delete":{"tags":["Snapshot"],"summary":"Delete snapshot","description":"Delete snapshot","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}},{"name":"snapshotId","in":"path","description":"Snapshot ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/workerStatus":{"get":{"tags":["Status"],"summary":"List worker status","description":"List of worker status","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.WorkerStatusRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/zones":{"get":{"tags":["Zone"],"summary":"List zones","description":"List zones","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.ZoneRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}}},"components":{"schemas":{"body.ApiKey":{"type":"object","properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}}},"body.ApiKeyCreate":{"required":["expiresAt","name"],"type":"object","properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}}},"body.ApiKeyCreated":{"type":"object","properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}}},"body.BindingError":{"type":"object","properties":{"validationErrors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"body.CiConfig":{"type":"object","properties":{"config":{"type":"string"}}},"body.ClusterCapacities":{"type":"object","properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}}},"body.ClusterStats":{"type":"object","properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}}},"body.CpuCoreCapacities":{"type":"object","properties":{"total":{"type":"integer"}}},"body.CpuStatus":{"type":"object","properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}}},"body.CpuStatusLoad":{"type":"object","properties":{"cores":{"type":"array","items":{"type":"integer"}},"main":{"type":"number"},"max":{"type":"number"}}},"body.CpuStatusTemp":{"type":"object","properties":{"cores":{"type":"array","items":{"type":"integer"}},"main":{"type":"number"},"max":{"type":"number"}}},"body.CustomDomainRead":{"type":"object","properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}}},"body.DeploymentCommand":{"required":["command"],"type":"object","properties":{"command":{"type":"string","enum":["restart"]}}},"body.DeploymentCreate":{"required":["name"],"type":"object","properties":{"args":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"cpuCores":{"minimum":0.1,"type":"number"},"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"envs":{"maxItems":1000,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Env"}},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"type":"boolean","description":"Deprecated: Use Visibility instead."},"ram":{"minimum":0.1,"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"type":"string","enum":["public","private","auth"]},"volumes":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Volume"}},"zone":{"type":"string","description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone."}}},"body.DeploymentCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.DeploymentRead":{"type":"object","properties":{"accessedAt":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"type":"array","items":{"$ref":"#/components/schemas/body.Env"}},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"type":"array","items":{"type":"string"}},"integrations":{"type":"array","description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"}},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"type":"boolean","description":"Deprecated: Use Visibility instead."},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"type":"array","items":{"type":"string"}},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"type":"array","items":{"$ref":"#/components/schemas/body.Volume"}},"zone":{"type":"string"}}},"body.DeploymentSpecs":{"type":"object","properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}}},"body.DeploymentUpdate":{"required":["name"],"type":"object","properties":{"args":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"cpuCores":{"minimum":0.1,"type":"number"},"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"envs":{"maxItems":1000,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Env"}},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"type":"boolean","description":"Deprecated: Use Visibility instead."},"ram":{"minimum":0.1,"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"type":"string","enum":["public","private","auth"]},"volumes":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Volume"}}}},"body.DeploymentUpdated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.DiscoverRead":{"type":"object","properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/body.Role"}},"version":{"type":"string"}}},"body.Env":{"required":["name","value"],"type":"object","properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}}},"body.GpuCapacities":{"type":"object","properties":{"total":{"type":"integer"}}},"body.GpuGroupRead":{"type":"object","properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}}},"body.GpuLeaseCreate":{"required":["gpuGroupId"],"type":"object","properties":{"gpuGroupId":{"type":"string","description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease."},"leaseForever":{"type":"boolean","description":"LeaseForever is used to specify whether the lease should be created forever."}}},"body.GpuLeaseCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.GpuLeaseDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.GpuLeaseRead":{"type":"object","properties":{"activatedAt":{"type":"string","description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU."},"active":{"type":"boolean"},"assignedAt":{"type":"string","description":"AssignedAt specifies the time when the lease was assigned to the user."},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"type":"string","description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active."},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"type":"string","description":"VmID is set when the lease is attached to a VM."}}},"body.GpuLeaseUpdate":{"type":"object","properties":{"vmId":{"type":"string","description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned."}}},"body.GpuLeaseUpdated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.GpuStatus":{"type":"object","properties":{"temp":{"type":"array","items":{"$ref":"#/components/schemas/body.GpuStatusTemp"}}}},"body.GpuStatusTemp":{"type":"object","properties":{"main":{"type":"number"}}},"body.HarborWebhook":{"type":"object","properties":{"event_data":{"type":"object","properties":{"repository":{"type":"object","properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}}},"resources":{"type":"array","items":{"type":"object","properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}}}}}},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}}},"body.HostCapacities":{"type":"object","properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"type":"string","description":"Zone is the name of the zone where the host is located."}}},"body.HostRead":{"type":"object","properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"type":"string","description":"Zone is the name of the zone where the host is located."}}},"body.HostStatus":{"type":"object","properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"type":"string","description":"Zone is the name of the zone where the host is located."}}},"body.HttpProxyCreate":{"required":["name"],"type":"object","properties":{"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"name":{"maxLength":30,"minLength":3,"type":"string"}}},"body.HttpProxyRead":{"type":"object","properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}}},"body.HttpProxyUpdate":{"required":["name"],"type":"object","properties":{"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"name":{"maxLength":30,"minLength":3,"type":"string"}}},"body.JobRead":{"type":"object","properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}}},"body.JobUpdate":{"type":"object","properties":{"status":{"type":"string","enum":["pending","running","failed","terminated","finished","completed"]}}},"body.K8sStats":{"type":"object","properties":{"clusters":{"type":"array","items":{"$ref":"#/components/schemas/body.ClusterStats"}},"podCount":{"type":"integer"}}},"body.NotificationRead":{"type":"object","properties":{"completedAt":{"type":"string"},"content":{"type":"object","additionalProperties":true},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}}},"body.NotificationUpdate":{"type":"object","properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}}},"body.PortCreate":{"required":["name","port","protocol"],"type":"object","properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"type":"string","enum":["tcp","udp"]}}},"body.PortRead":{"type":"object","properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}}},"body.PortUpdate":{"required":["name","port","protocol"],"type":"object","properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"type":"string","enum":["tcp","udp"]}}},"body.PublicKey":{"required":["key","name"],"type":"object","properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}}},"body.Quota":{"type":"object","properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"type":"number","description":"in hours"},"ram":{"type":"number"},"snapshots":{"type":"integer"}}},"body.RamCapacities":{"type":"object","properties":{"total":{"type":"integer"}}},"body.RamStatus":{"type":"object","properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}}},"body.RamStatusLoad":{"type":"object","properties":{"main":{"type":"number"}}},"body.ReplicaStatus":{"type":"object","properties":{"availableReplicas":{"type":"integer","description":"AvailableReplicas is the number of replicas that are available."},"desiredReplicas":{"type":"integer","description":"DesiredReplicas is the number of replicas that the deployment should have."},"readyReplicas":{"type":"integer","description":"ReadyReplicas is the number of replicas that are ready."},"unavailableReplicas":{"type":"integer","description":"UnavailableReplicas is the number of replicas that are unavailable."}}},"body.ResourceMigrationCreate":{"required":["resourceId","type"],"type":"object","properties":{"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"status":{"type":"string","description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending"},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"]},"updateOwner":{"required":["ownerId"],"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner."}}},"body.ResourceMigrationCreated":{"type":"object","properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"type":"string","description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'."},"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"resourceType":{"type":"string","description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment"},"status":{"type":"string","description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted."},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner"},"updateOwner":{"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner."},"userId":{"type":"string","description":"UserID is the ID of the user who initiated the migration."}}},"body.ResourceMigrationRead":{"type":"object","properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"resourceType":{"type":"string","description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment"},"status":{"type":"string","description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted."},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner"},"updateOwner":{"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner."},"userId":{"type":"string","description":"UserID is the ID of the user who initiated the migration."}}},"body.ResourceMigrationUpdate":{"required":["status"],"type":"object","properties":{"code":{"type":"string","description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API"},"status":{"type":"string","description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending"}}},"body.ResourceMigrationUpdated":{"type":"object","properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"type":"string","description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'."},"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"resourceType":{"type":"string","description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment"},"status":{"type":"string","description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted."},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner"},"updateOwner":{"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner."},"userId":{"type":"string","description":"UserID is the ID of the user who initiated the migration."}}},"body.Role":{"type":"object","properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}},"quota":{"$ref":"#/components/schemas/body.Quota"}}},"body.SmDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.SmRead":{"type":"object","properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}}},"body.SystemCapacities":{"type":"object","properties":{"clusters":{"type":"array","description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"}},"cpuCore":{"type":"object","description":"Total","allOf":[{"$ref":"#/components/schemas/body.CpuCoreCapacities"}]},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"type":"array","description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"}},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}}},"body.SystemStats":{"type":"object","properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}}},"body.SystemStatus":{"type":"object","properties":{"hosts":{"type":"array","items":{"$ref":"#/components/schemas/body.HostStatus"}}}},"body.TeamCreate":{"required":["name"],"type":"object","properties":{"description":{"maxLength":1000,"type":"string"},"members":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.TeamMemberCreate"}},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}}}},"body.TeamMember":{"type":"object","properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}}},"body.TeamMemberCreate":{"required":["id"],"type":"object","properties":{"id":{"type":"string"},"teamRole":{"type":"string","description":"default to MemberRoleAdmin right now"}}},"body.TeamMemberUpdate":{"required":["id"],"type":"object","properties":{"id":{"type":"string"},"teamRole":{"type":"string","description":"default to MemberRoleAdmin right now"}}},"body.TeamRead":{"type":"object","properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"type":"array","items":{"$ref":"#/components/schemas/body.TeamMember"}},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"type":"array","items":{"$ref":"#/components/schemas/body.TeamResource"}},"updatedAt":{"type":"string"}}},"body.TeamResource":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}}},"body.TeamUpdate":{"type":"object","properties":{"description":{"maxLength":1000,"type":"string"},"members":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"}},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}}}},"body.TimestampedSystemCapacities":{"type":"object","properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}}},"body.TimestampedSystemStats":{"type":"object","properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}}},"body.TimestampedSystemStatus":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}}},"body.Usage":{"type":"object","properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}}},"body.UserData":{"required":["key","value"],"type":"object","properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}}},"body.UserRead":{"type":"object","properties":{"admin":{"type":"boolean"},"apiKeys":{"type":"array","items":{"$ref":"#/components/schemas/body.ApiKey"}},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"type":"array","items":{"$ref":"#/components/schemas/body.PublicKey"}},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"type":"array","items":{"$ref":"#/components/schemas/body.UserData"}},"username":{"type":"string"}}},"body.UserUpdate":{"type":"object","properties":{"apiKeys":{"maxItems":100,"minItems":0,"type":"array","description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"}},"publicKeys":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.PublicKey"}},"userData":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.UserData"}}}},"body.VmActionCreate":{"required":["action"],"type":"object","properties":{"action":{"type":"string","enum":["start","stop","restart","repair"]}}},"body.VmActionCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmCreate":{"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object","properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"maxItems":10,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.PortCreate"}},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}}},"body.VmCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmGpuLease":{"type":"object","properties":{"activatedAt":{"type":"string","description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU."},"assignedAt":{"type":"string","description":"AssignedAt specifies the time when the lease was assigned to the user."},"createdAt":{"type":"string"},"expiredAt":{"type":"string","description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired."},"expiresAt":{"type":"string","description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active."},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}}},"body.VmRead":{"type":"object","properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/body.PortRead"}},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string"},"zone":{"type":"string"}}},"body.VmSnapshotCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmSnapshotDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmSnapshotRead":{"type":"object","properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}}},"body.VmSpecs":{"type":"object","properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}}},"body.VmUpdate":{"type":"object","properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"maxItems":10,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.PortUpdate"}},"ram":{"minimum":1,"type":"integer"}}},"body.VmUpdated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.Volume":{"required":["appPath","name","serverPath"],"type":"object","properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}}},"body.WorkerStatusRead":{"type":"object","properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}}},"body.ZoneEndpoints":{"type":"object","properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}}},"body.ZoneRead":{"type":"object","properties":{"capabilities":{"type":"array","items":{"type":"string"}},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}}},"sys.Error":{"type":"object","properties":{"code":{"type":"string"},"msg":{"type":"string"}}},"sys.ErrorResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/sys.Error"}}}}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"X-Api-Key","in":"header"},"KeycloakOAuth":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token","scopes":{"email":"email","openid":"openid","profile":"profile"}}}}}},"x-original-swagger-version":"2.0"} diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index f9f431af..c9c52eae 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -1,3516 +1,4001 @@ -definitions: - body.ApiKey: - properties: - createdAt: - type: string - expiresAt: - type: string - name: - type: string - type: object - body.ApiKeyCreate: - properties: - expiresAt: - type: string - name: - type: string - required: - - expiresAt - - name - type: object - body.ApiKeyCreated: - properties: - createdAt: - type: string - expiresAt: - type: string - key: - type: string - name: - type: string - type: object - body.BindingError: - properties: - validationErrors: - additionalProperties: - items: - type: string - type: array - type: object - type: object - body.CiConfig: - properties: - config: - type: string - type: object - body.CpuCoreCapacities: - properties: - total: - type: integer - type: object - body.CustomDomainRead: - properties: - domain: - type: string - secret: - type: string - status: - type: string - url: - type: string - type: object - body.DeploymentCommand: - properties: - command: - enum: - - restart - type: string - required: - - command - type: object - body.DeploymentCreate: - properties: - args: - items: - type: string - maxItems: 100 - minItems: 0 - type: array - cpuCores: - minimum: 0.1 - type: number - customDomain: - description: |- - CustomDomain is the domain that the deployment will be available on. - The max length is set to 243 to allow for a subdomain when confirming the domain. - type: string - envs: - items: - $ref: '#/definitions/body.Env' - maxItems: 1000 - minItems: 0 - type: array - healthCheckPath: - maxLength: 1000 - minLength: 0 - type: string - image: - maxLength: 1000 - minLength: 1 - type: string - initCommands: - items: - type: string - maxItems: 100 - minItems: 0 - type: array - name: - maxLength: 30 - minLength: 3 - type: string - private: - type: boolean - ram: - minimum: 0.1 - type: number - replicas: - maximum: 100 - minimum: 0 - type: integer - volumes: - items: - $ref: '#/definitions/body.Volume' - maxItems: 100 - minItems: 0 - type: array - zone: - description: |- - Zone is the zone that the deployment will be created in. - If the zone is not set, the deployment will be created in the default zone. - type: string - required: - - name - type: object - body.DeploymentCreated: - properties: - id: - type: string - jobId: - type: string - type: object - body.DeploymentRead: - properties: - accessedAt: - type: string - args: - items: - type: string - type: array - createdAt: - type: string - customDomain: - $ref: '#/definitions/body.CustomDomainRead' - envs: - items: - $ref: '#/definitions/body.Env' - type: array - error: - type: string - healthCheckPath: - type: string - id: - type: string - image: - type: string - initCommands: - items: - type: string - type: array - integrations: - description: |- - Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment - - For example GitHub - items: - type: string - type: array - internalPort: - type: integer - name: - type: string - ownerId: - type: string - pingResult: - type: integer - private: - type: boolean - repairedAt: - type: string - replicaStatus: - $ref: '#/definitions/body.ReplicaStatus' - restartedAt: - type: string - specs: - $ref: '#/definitions/body.DeploymentSpecs' - status: - type: string - storageUrl: - type: string - teams: - items: - type: string - type: array - type: - type: string - updatedAt: - type: string - url: - type: string - volumes: - items: - $ref: '#/definitions/body.Volume' - type: array - zone: - type: string - type: object - body.DeploymentSpecs: - properties: - cpuCores: - type: number - ram: - type: number - replicas: - type: integer - type: object - body.DeploymentUpdate: - properties: - args: - items: - type: string - maxItems: 100 - minItems: 0 - type: array - cpuCores: - minimum: 0.1 - type: number - customDomain: - description: |- - CustomDomain is the domain that the deployment will be available on. - The max length is set to 243 to allow for a subdomain when confirming the domain. - type: string - envs: - items: - $ref: '#/definitions/body.Env' - maxItems: 1000 - minItems: 0 - type: array - healthCheckPath: - maxLength: 1000 - minLength: 0 - type: string - image: - maxLength: 1000 - minLength: 1 - type: string - initCommands: - items: - type: string - maxItems: 100 - minItems: 0 - type: array - name: - maxLength: 30 - minLength: 3 - type: string - private: - type: boolean - ram: - minimum: 0.1 - type: number - replicas: - maximum: 100 - minimum: 0 - type: integer - volumes: - items: - $ref: '#/definitions/body.Volume' - maxItems: 100 - minItems: 0 - type: array - required: - - name - type: object - body.DeploymentUpdated: - properties: - id: - type: string - jobId: - type: string - type: object - body.DiscoverRead: - properties: - roles: - items: - $ref: '#/definitions/body.Role' - type: array - version: - type: string - type: object - body.Env: - properties: - name: - maxLength: 100 - minLength: 1 - type: string - value: - maxLength: 10000 - minLength: 1 - type: string - required: - - name - - value - type: object - body.GpuCapacities: - properties: - total: - type: integer - type: object - body.GpuGroupRead: - properties: - available: - type: integer - displayName: - type: string - id: - type: string - name: - type: string - total: - type: integer - vendor: - type: string - zone: - type: string - type: object - body.GpuLeaseCreate: - properties: - gpuGroupId: - description: |- - GpuGroupID is used to specify the GPU to lease. - As such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease. - type: string - leaseForever: - description: LeaseForever is used to specify whether the lease should be created - forever. - type: boolean - required: - - gpuGroupId - type: object - body.GpuLeaseCreated: - properties: - id: - type: string - jobId: - type: string - type: object - body.GpuLeaseDeleted: - properties: - id: - type: string - jobId: - type: string - type: object - body.GpuLeaseRead: - properties: - activatedAt: - description: |- - ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU - or 1 day after the lease was created if the user did not attach the GPU. - type: string - active: - type: boolean - assignedAt: - description: AssignedAt specifies the time when the lease was assigned to - the user. - type: string - createdAt: - type: string - expiredAt: - type: string - expiresAt: - description: |- - ExpiresAt specifies the time when the lease will expire. - This is only present if the lease is active. - type: string - gpuGroupId: - type: string - id: - type: string - leaseDuration: - type: number - queuePosition: - type: integer - userId: - type: string - vmId: - description: VmID is set when the lease is attached to a VM. - type: string - type: object - body.GpuLeaseUpdate: - properties: - vmId: - description: |- - VmID is used to specify the VM to attach the lease to. - - - If specified, the lease will be attached to the VM. - - - If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM. - - - If the lease is not active, specifying a VM will activate the lease. - - - If the lease is not assigned, an error will be returned. - type: string - type: object - body.GpuLeaseUpdated: - properties: - id: - type: string - jobId: - type: string - type: object - body.HarborWebhook: - properties: - event_data: - properties: - repository: - properties: - date_created: - type: integer - name: - type: string - namespace: - type: string - repo_full_name: - type: string - repo_type: - type: string - type: object - resources: - items: - properties: - digest: - type: string - resource_url: - type: string - tag: - type: string - type: object - type: array - type: object - occur_at: - type: integer - operator: - type: string - type: - type: string - type: object - body.HostCapacities: - properties: - displayName: - type: string - gpu: - properties: - count: - type: integer - type: object - name: - type: string - ram: - properties: - total: - type: integer - type: object - zone: - description: Zone is the name of the zone where the host is located. - type: string - type: object - body.HostRead: - properties: - displayName: - type: string - name: - type: string - zone: - description: Zone is the name of the zone where the host is located. - type: string - type: object - body.HttpProxyCreate: - properties: - customDomain: - description: |- - CustomDomain is the domain that the deployment will be available on. - The max length is set to 243 to allow for a sub domain when confirming the domain. - type: string - name: - maxLength: 30 - minLength: 3 - type: string - required: - - name - type: object - body.HttpProxyRead: - properties: - customDomain: - $ref: '#/definitions/body.CustomDomainRead' - name: - maxLength: 30 - minLength: 3 - type: string - url: - type: string - required: - - name - type: object - body.HttpProxyUpdate: - properties: - customDomain: - description: |- - CustomDomain is the domain that the deployment will be available on. - The max length is set to 243 to allow for a sub domain when confirming the domain. - type: string - name: - maxLength: 30 - minLength: 3 - type: string - required: - - name - type: object - body.JobRead: - properties: - createdAt: - type: string - finishedAt: - type: string - id: - type: string - lastError: - type: string - lastRunAt: - type: string - runAfter: - type: string - status: - type: string - type: - type: string - userId: - type: string - type: object - body.JobUpdate: - properties: - status: - enum: - - pending - - running - - failed - - terminated - - finished - - completed - type: string - type: object - body.NotificationRead: - properties: - completedAt: - type: string - content: - additionalProperties: true - type: object - createdAt: - type: string - id: - type: string - readAt: - type: string - type: - type: string - userId: - type: string - type: object - body.NotificationUpdate: - properties: - read: - type: boolean - type: object - body.PortCreate: - properties: - httpProxy: - $ref: '#/definitions/body.HttpProxyCreate' - name: - maxLength: 100 - minLength: 1 - type: string - port: - maximum: 65535 - minimum: 1 - type: integer - protocol: - enum: - - tcp - - udp - type: string - required: - - name - - port - - protocol - type: object - body.PortRead: - properties: - externalPort: - type: integer - httpProxy: - $ref: '#/definitions/body.HttpProxyRead' - name: - type: string - port: - type: integer - protocol: - type: string - type: object - body.PortUpdate: - properties: - httpProxy: - $ref: '#/definitions/body.HttpProxyUpdate' - name: - maxLength: 100 - minLength: 1 - type: string - port: - maximum: 65535 - minimum: 1 - type: integer - protocol: - enum: - - tcp - - udp - type: string - required: - - name - - port - - protocol - type: object - body.PublicKey: - properties: - key: - type: string - name: - maxLength: 30 - minLength: 1 - type: string - required: - - key - - name - type: object - body.Quota: - properties: - cpuCores: - type: number - diskSize: - type: number - gpuLeaseDuration: - description: in hours - type: number - ram: - type: number - snapshots: - type: integer - type: object - body.RamCapacities: - properties: - total: - type: integer - type: object - body.ReplicaStatus: - properties: - availableReplicas: - description: AvailableReplicas is the number of replicas that are available. - type: integer - desiredReplicas: - description: DesiredReplicas is the number of replicas that the deployment - should have. - type: integer - readyReplicas: - description: ReadyReplicas is the number of replicas that are ready. - type: integer - unavailableReplicas: - description: UnavailableReplicas is the number of replicas that are unavailable. - type: integer - type: object - body.ResourceMigrationCreate: - properties: - resourceId: - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - type: string - status: - description: |- - Status is the status of the resource migration. - It is used by privileged admins to directly accept or reject a migration. - The field is ignored by non-admins. - - Possible values: - - accepted - - pending - type: string - type: - description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - enum: - - updateOwner - type: string - updateOwner: - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is ignored if the migration type is not updateOwner. - properties: - ownerId: - type: string - required: - - ownerId - type: object - required: - - resourceId - - type - type: object - body.ResourceMigrationCreated: - properties: - createdAt: - type: string - deletedAt: - type: string - id: - type: string - jobId: - description: |- - JobID is the ID of the job that was created for the resource migration. - It will only be set if the migration was created with status 'accepted'. - type: string - resourceId: - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - type: string - resourceType: - description: |- - ResourceType is the type of the resource that is being migrated. - - Possible values: - - vm - - deployment - type: string - status: - description: |- - Status is the status of the resource migration. - When this field is set to 'accepted', the migration will take place and then automatically be deleted. - type: string - type: - description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - type: string - updateOwner: - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is empty if the migration type is not updateOwner. - properties: - ownerId: - type: string - type: object - userId: - description: UserID is the ID of the user who initiated the migration. - type: string - type: object - body.ResourceMigrationRead: - properties: - createdAt: - type: string - deletedAt: - type: string - id: - type: string - resourceId: - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - type: string - resourceType: - description: |- - ResourceType is the type of the resource that is being migrated. - - Possible values: - - vm - - deployment - type: string - status: - description: |- - Status is the status of the resource migration. - When this field is set to 'accepted', the migration will take place and then automatically be deleted. - type: string - type: - description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - type: string - updateOwner: - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is empty if the migration type is not updateOwner. - properties: - ownerId: - type: string - type: object - userId: - description: UserID is the ID of the user who initiated the migration. - type: string - type: object - body.ResourceMigrationUpdate: - properties: - code: - description: |- - Code is a token required when accepting a migration if the acceptor is not an admin. - It is sent to the acceptor using the notification API - type: string - status: - description: |- - Status is the status of the resource migration. - It is used to accept a migration by setting the status to 'accepted'. - If the acceptor is not an admin, a Code must be provided. - - Possible values: - - accepted - - pending - type: string - required: - - status - type: object - body.ResourceMigrationUpdated: - properties: - createdAt: - type: string - deletedAt: - type: string - id: - type: string - jobId: - description: |- - JobID is the ID of the job that was created for the resource migration. - It will only be set if the migration was updated with status 'accepted'. - type: string - resourceId: - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - type: string - resourceType: - description: |- - ResourceType is the type of the resource that is being migrated. - - Possible values: - - vm - - deployment - type: string - status: - description: |- - Status is the status of the resource migration. - When this field is set to 'accepted', the migration will take place and then automatically be deleted. - type: string - type: - description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - type: string - updateOwner: - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is empty if the migration type is not updateOwner. - properties: - ownerId: - type: string - type: object - userId: - description: UserID is the ID of the user who initiated the migration. - type: string - type: object - body.Role: - properties: - description: - type: string - name: - type: string - permissions: - items: - type: string - type: array - quota: - $ref: '#/definitions/body.Quota' - type: object - body.SmDeleted: - properties: - id: - type: string - jobId: - type: string - type: object - body.SmRead: - properties: - createdAt: - type: string - id: - type: string - ownerId: - type: string - url: - type: string - zone: - type: string - type: object - body.SystemCapacities: - properties: - cpuCore: - $ref: '#/definitions/body.CpuCoreCapacities' - gpu: - $ref: '#/definitions/body.GpuCapacities' - hosts: - items: - $ref: '#/definitions/body.HostCapacities' - type: array - ram: - $ref: '#/definitions/body.RamCapacities' - type: object - body.TeamCreate: - properties: - description: - maxLength: 1000 - type: string - members: - items: - $ref: '#/definitions/body.TeamMemberCreate' - maxItems: 100 - minItems: 0 - type: array - name: - maxLength: 100 - minLength: 1 - type: string - resources: - items: - type: string - maxItems: 100 - minItems: 0 - type: array - required: - - name - type: object - body.TeamMember: - properties: - addedAt: - type: string - email: - type: string - firstName: - type: string - gravatarUrl: - type: string - id: - type: string - joinedAt: - type: string - lastName: - type: string - memberStatus: - type: string - teamRole: - type: string - username: - type: string - type: object - body.TeamMemberCreate: - properties: - id: - type: string - teamRole: - description: default to MemberRoleAdmin right now - type: string - required: - - id - type: object - body.TeamMemberUpdate: - properties: - id: - type: string - teamRole: - description: default to MemberRoleAdmin right now - type: string - required: - - id - type: object - body.TeamRead: - properties: - createdAt: - type: string - description: - type: string - id: - type: string - members: - items: - $ref: '#/definitions/body.TeamMember' - type: array - name: - type: string - ownerId: - type: string - resources: - items: - $ref: '#/definitions/body.TeamResource' - type: array - updatedAt: - type: string - type: object - body.TeamResource: - properties: - id: - type: string - name: - type: string - type: - type: string - type: object - body.TeamUpdate: - properties: - description: - maxLength: 1000 - type: string - members: - items: - $ref: '#/definitions/body.TeamMemberUpdate' - maxItems: 100 - minItems: 0 - type: array - name: - maxLength: 100 - minLength: 1 - type: string - resources: - items: - type: string - maxItems: 100 - minItems: 0 - type: array - type: object - body.TimestampedSystemCapacities: - properties: - capacities: - $ref: '#/definitions/body.SystemCapacities' - timestamp: - type: string - type: object - body.Usage: - properties: - cpuCores: - type: number - diskSize: - type: integer - ram: - type: number - type: object - body.UserData: - properties: - key: - maxLength: 255 - minLength: 1 - type: string - value: - maxLength: 255 - minLength: 1 - type: string - required: - - key - - value - type: object - body.UserRead: - properties: - admin: - type: boolean - apiKeys: - items: - $ref: '#/definitions/body.ApiKey' - type: array - email: - type: string - firstName: - type: string - gravatarUrl: - type: string - id: - type: string - lastName: - type: string - publicKeys: - items: - $ref: '#/definitions/body.PublicKey' - type: array - quota: - $ref: '#/definitions/body.Quota' - role: - $ref: '#/definitions/body.Role' - storageUrl: - type: string - usage: - $ref: '#/definitions/body.Usage' - userData: - items: - $ref: '#/definitions/body.UserData' - type: array - username: - type: string - type: object - body.UserUpdate: - properties: - apiKeys: - description: |- - ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted. - However, API keys cannot be created, use /apiKeys endpoint to create new API keys. - items: - $ref: '#/definitions/body.ApiKey' - maxItems: 100 - minItems: 0 - type: array - publicKeys: - items: - $ref: '#/definitions/body.PublicKey' - maxItems: 100 - minItems: 0 - type: array - userData: - items: - $ref: '#/definitions/body.UserData' - maxItems: 100 - minItems: 0 - type: array - type: object - body.VmActionCreate: - properties: - action: - enum: - - start - - stop - - restart - - repair - type: string - required: - - action - type: object - body.VmActionCreated: - properties: - id: - type: string - jobId: - type: string - type: object - body.VmCreate: - properties: - cpuCores: - minimum: 1 - type: integer - diskSize: - minimum: 10 - type: integer - name: - maxLength: 30 - minLength: 3 - type: string - ports: - items: - $ref: '#/definitions/body.PortCreate' - maxItems: 10 - minItems: 0 - type: array - ram: - minimum: 1 - type: integer - sshPublicKey: - type: string - zone: - type: string - required: - - cpuCores - - diskSize - - name - - ram - - sshPublicKey - type: object - body.VmCreated: - properties: - id: - type: string - jobId: - type: string - type: object - body.VmDeleted: - properties: - id: - type: string - jobId: - type: string - type: object - body.VmGpuLease: - properties: - activatedAt: - description: |- - ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU - or 1 day after the lease was created if the user did not attach the GPU. - type: string - assignedAt: - description: AssignedAt specifies the time when the lease was assigned to - the user. - type: string - createdAt: - type: string - expiredAt: - description: |- - ExpiredAt specifies the time when the lease expired. - This is only present if the lease is expired. - type: string - expiresAt: - description: |- - ExpiresAt specifies the time when the lease will expire. - This is only present if the lease is active. - type: string - gpuGroupId: - type: string - id: - type: string - leaseDuration: - type: number - type: object - body.VmRead: - properties: - accessedAt: - type: string - createdAt: - type: string - gpu: - $ref: '#/definitions/body.VmGpuLease' - host: - type: string - id: - type: string - internalName: - type: string - name: - type: string - ownerId: - type: string - ports: - items: - $ref: '#/definitions/body.PortRead' - type: array - repairedAt: - type: string - specs: - $ref: '#/definitions/body.VmSpecs' - sshConnectionString: - type: string - sshPublicKey: - type: string - status: - type: string - teams: - items: - type: string - type: array - updatedAt: - type: string - zone: - type: string - type: object - body.VmSnapshotCreated: - properties: - id: - type: string - jobId: - type: string - type: object - body.VmSnapshotDeleted: - properties: - id: - type: string - jobId: - type: string - type: object - body.VmSnapshotRead: - properties: - created: - type: string - id: - type: string - name: - type: string - status: - type: string - type: object - body.VmSpecs: - properties: - cpuCores: - type: integer - diskSize: - type: integer - ram: - type: integer - type: object - body.VmUpdate: - properties: - cpuCores: - minimum: 1 - type: integer - name: - description: |- - Name is used to rename a VM. - If specified, only name will be updated. - maxLength: 30 - minLength: 3 - type: string - ownerId: - description: |- - OwnerID is used to initiate transfer a VM to another user. - If specified, only the transfer will happen. - If specified but empty, the transfer will be canceled. - type: string - ports: - items: - $ref: '#/definitions/body.PortUpdate' - maxItems: 10 - minItems: 0 - type: array - ram: - minimum: 1 - type: integer - type: object - body.VmUpdated: - properties: - id: - type: string - jobId: - type: string - type: object - body.Volume: - properties: - appPath: - maxLength: 255 - minLength: 1 - type: string - name: - maxLength: 30 - minLength: 3 - type: string - serverPath: - maxLength: 255 - minLength: 1 - type: string - required: - - appPath - - name - - serverPath - type: object - body.WorkerStatusRead: - properties: - name: - type: string - reportedAt: - type: string - status: - type: string - type: object - body.ZoneEndpoints: - properties: - deployment: - type: string - storage: - type: string - vm: - type: string - vmApp: - type: string - type: object - body.ZoneRead: - properties: - capabilities: - items: - type: string - type: array - description: - type: string - enabled: - type: boolean - endpoints: - $ref: '#/definitions/body.ZoneEndpoints' - legacy: - type: boolean - name: - type: string - type: object - sys.Error: - properties: - code: - type: string - msg: - type: string - type: object - sys.ErrorResponse: - properties: - errors: - items: - $ref: '#/definitions/sys.Error' - type: array - type: object +openapi: 3.0.1 info: + title: go-deploy API + description: This is the API explorer for the go-deploy API. You can use it as a + reference for the API endpoints. + termsOfService: http://swagger.io/terms/ contact: name: Support url: https://github.com/kthcloud/go-deploy - description: This is the API explorer for the go-deploy API. You can use it as a - reference for the API endpoints. license: name: MIT License url: https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme - termsOfService: http://swagger.io/terms/ - title: go-deploy API version: "1.0" +servers: +- url: / paths: /v2/deployments: get: - consumes: - - application/json + tags: + - Deployment + summary: List deployments description: List deployments parameters: - - description: List all + - name: all in: query - name: all - type: boolean - - description: Filter by user ID + description: List all + schema: + type: boolean + - name: userId in: query - name: userId - type: string - - description: Include shared + description: Filter by user ID + schema: + type: string + - name: shared in: query - name: shared - type: boolean - - description: Page number + description: Include shared + schema: + type: boolean + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.DeploymentRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.DeploymentRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List deployments + - KeycloakOAuth: [] + post: tags: - Deployment - post: - consumes: - - application/json + summary: Create deployment description: Create deployment - parameters: - - description: Deployment body - in: body - name: body + requestBody: + description: Deployment body + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentCreate' required: true - schema: - $ref: '#/definitions/body.DeploymentCreate' - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.DeploymentRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Create deployment + - KeycloakOAuth: [] + x-codegen-request-body-name: body + /v2/deployments/{deploymentId}: + get: tags: - Deployment - /v2/deployments/{deploymentId}: - delete: - consumes: - - application/json - description: Delete deployment + summary: Get deployment + description: Get deployment parameters: - - description: Deployment ID + - name: deploymentId in: path - name: deploymentId + description: Deployment ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.DeploymentCreated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' - "401": - description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' - "404": - description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete deployment + - KeycloakOAuth: [] + post: tags: - Deployment - get: - consumes: - - application/json - description: Get deployment + summary: Update deployment + description: Update deployment parameters: - - description: Deployment ID + - name: deploymentId in: path - name: deploymentId + description: Deployment ID + required: true + schema: + type: string + requestBody: + description: Deployment update + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentUpdate' required: true - type: string - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.DeploymentRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentUpdated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get deployment + - KeycloakOAuth: [] + x-codegen-request-body-name: body + delete: tags: - Deployment - post: - consumes: - - application/json - description: Update deployment + summary: Delete deployment + description: Delete deployment parameters: - - description: Deployment ID + - name: deploymentId in: path - name: deploymentId - required: true - type: string - - description: Deployment update - in: body - name: body + description: Deployment ID required: true schema: - $ref: '#/definitions/body.DeploymentUpdate' - produces: - - application/json + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.DeploymentUpdated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentCreated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Update deployment - tags: - - Deployment + - KeycloakOAuth: [] /v2/deployments/{deploymentId}/ciConfig: get: - consumes: - - application/json + tags: + - Deployment + summary: Get CI config description: Get CI config parameters: - - description: Deployment ID + - name: deploymentId in: path - name: deploymentId + description: Deployment ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.CiConfig' + content: + application/json: + schema: + $ref: '#/components/schemas/body.CiConfig' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get CI config - tags: - - Deployment + - KeycloakOAuth: [] /v2/deployments/{deploymentId}/command: post: - consumes: - - application/json + tags: + - Deployment + summary: Do command description: Do command parameters: - - description: Deployment ID + - name: deploymentId in: path - name: deploymentId - required: true - type: string - - description: Command body - in: body - name: body + description: Deployment ID required: true schema: - $ref: '#/definitions/body.DeploymentCommand' - produces: - - application/json + type: string + requestBody: + description: Command body + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentCommand' + required: true responses: "204": description: No Content + content: {} "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "423": description: Locked - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Do command - tags: - - Deployment + - KeycloakOAuth: [] + x-codegen-request-body-name: body /v2/deployments/{deploymentId}/logs: get: - consumes: - - application/json + tags: + - Deployment + summary: Get logs using Server-Sent Events description: Get logs using Server-Sent Events parameters: - - description: Deployment ID + - name: deploymentId in: path - name: deploymentId + description: Deployment ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - type: string + content: + application/json: + schema: + type: string "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get logs using Server-Sent Events - tags: - - Deployment + - KeycloakOAuth: [] /v2/discover: get: - consumes: - - application/json + tags: + - Discover + summary: Discover description: Discover - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.DiscoverRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.DiscoverRead' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: Discover - tags: - - Discover + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/gpuGroups: get: - consumes: - - application/json + tags: + - GpuGroup + summary: List GPU groups description: List GPU groups parameters: - - description: Page number + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.GpuGroupRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.GpuGroupRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "423": description: Locked - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List GPU groups - tags: - - GpuGroup + - KeycloakOAuth: [] /v2/gpuGroups/{gpuGroupId}: get: - consumes: - - application/json + tags: + - GpuGroup + summary: Get GPU group description: Get GPU group parameters: - - description: GPU group ID + - name: gpuGroupId in: path - name: gpuGroupId + description: GPU group ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.GpuGroupRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuGroupRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "423": description: Locked - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get GPU group - tags: - - GpuGroup + - KeycloakOAuth: [] /v2/gpuLeases: get: - consumes: - - application/json + tags: + - GpuLease + summary: List GPU leases description: List GPU leases parameters: - - description: List all + - name: all in: query - name: all - type: boolean - - description: Filter by VM ID + description: List all + schema: + type: boolean + - name: vmId in: query - name: vmId - type: string - - description: Page number + description: Filter by VM ID + schema: + type: string + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.GpuLeaseRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.GpuLeaseRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "423": description: Locked - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List GPU leases + - KeycloakOAuth: [] + post: tags: - GpuLease - post: - consumes: - - application/json + summary: Create GPU Lease description: Create GPU lease - parameters: - - description: GPU lease - in: body - name: body + requestBody: + description: GPU lease + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseCreate' required: true - schema: - $ref: '#/definitions/body.GpuLeaseCreate' - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.GpuLeaseCreated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseCreated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Create GPU Lease + - KeycloakOAuth: [] + x-codegen-request-body-name: body + /v2/gpuLeases/{gpuLeaseId}: + get: tags: - GpuLease - /v2/gpuLeases/{gpuLeaseId}: - delete: - consumes: - - application/json - description: Delete GPU lease + summary: Get GPU lease + description: Get GPU lease parameters: - - description: GPU lease ID + - name: gpuLeaseId in: path - name: gpuLeaseId + description: GPU lease ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.GpuLeaseDeleted' + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + "423": + description: Locked + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete GPU lease + - KeycloakOAuth: [] + post: tags: - GpuLease - get: - consumes: - - application/json - description: Get GPU lease + summary: Update GPU lease + description: Update GPU lease parameters: - - description: GPU lease ID + - name: gpuLeaseId in: path - name: gpuLeaseId + description: GPU lease ID + required: true + schema: + type: string + requestBody: + description: GPU lease + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseUpdate' required: true - type: string - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.GpuLeaseRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseUpdated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' - "423": - description: Locked - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get GPU lease + - KeycloakOAuth: [] + x-codegen-request-body-name: body + delete: tags: - GpuLease - post: - consumes: - - application/json - description: Update GPU lease + summary: Delete GPU lease + description: Delete GPU lease parameters: - - description: GPU lease ID + - name: gpuLeaseId in: path - name: gpuLeaseId - required: true - type: string - - description: GPU lease - in: body - name: body + description: GPU lease ID required: true schema: - $ref: '#/definitions/body.GpuLeaseUpdate' - produces: - - application/json + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.GpuLeaseUpdated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseDeleted' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Update GPU lease - tags: - - GpuLease + - KeycloakOAuth: [] /v2/hooks/harbor: post: - consumes: - - application/json + tags: + - Deployment + summary: Handle Harbor hook description: Handle Harbor hook parameters: - - description: Basic auth token + - name: Authorization in: header - name: Authorization - type: string - - description: Harbor webhook body - in: body - name: body - required: true + description: Basic auth token schema: - $ref: '#/definitions/body.HarborWebhook' - produces: - - application/json + type: string + requestBody: + description: Harbor webhook body + content: + application/json: + schema: + $ref: '#/components/schemas/body.HarborWebhook' + required: true responses: "204": description: No Content + content: {} "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: Handle Harbor hook - tags: - - Deployment + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + x-codegen-request-body-name: body /v2/hosts: get: - consumes: - - application/json + tags: + - Host + summary: List Hosts description: List Hosts - produces: - - application/json responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.HostRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.HostRead' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: List Hosts - tags: - - Host + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/jobs: get: - consumes: - - application/json + tags: + - Job + summary: List jobs description: List jobs parameters: - - description: List all + - name: all in: query - name: all - type: boolean - - description: Filter by user ID + description: List all + schema: + type: boolean + - name: userId in: query - name: userId - type: string - - description: Filter by type + description: Filter by user ID + schema: + type: string + - name: type in: query - name: type - type: string - - description: Filter by status + description: Filter by type + schema: + type: string + - name: status in: query - name: status - type: string - - description: Page number + description: Filter by status + schema: + type: string + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.JobRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.JobRead' security: - ApiKeyAuth: [] - summary: List jobs - tags: - - Job + - KeycloakOAuth: [] /v2/jobs/{jobId}: get: - consumes: - - application/json + tags: + - Job + summary: GetJob job by id description: GetJob job by id parameters: - - description: Job ID + - name: jobId in: path - name: jobId + description: Job ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.JobRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.JobRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: GetJob job by id + - KeycloakOAuth: [] + post: tags: - Job - post: - consumes: - - application/json + summary: Update job description: Update job. Only allowed for admins. parameters: - - description: Job ID + - name: jobId in: path - name: jobId - required: true - type: string - - description: Job update - in: body - name: body + description: Job ID required: true schema: - $ref: '#/definitions/body.JobUpdate' - produces: - - application/json + type: string + requestBody: + description: Job update + content: + application/json: + schema: + $ref: '#/components/schemas/body.JobUpdate' + required: true responses: "200": description: OK - schema: - $ref: '#/definitions/body.JobRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.JobRead' security: - ApiKeyAuth: [] - summary: Update job - tags: - - Job + - KeycloakOAuth: [] + x-codegen-request-body-name: body /v2/metrics: get: - consumes: - - application/json + tags: + - Metrics + summary: Get metrics description: Get metrics - produces: - - application/json responses: "200": description: OK - schema: - type: string + content: + application/json: + schema: + type: string "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: Get metrics - tags: - - Metrics + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/notifications: get: - consumes: - - application/json + tags: + - Notification + summary: List notifications description: List notifications parameters: - - description: List all notifications + - name: all in: query - name: all - type: boolean - - description: Filter by user ID + description: List all notifications + schema: + type: boolean + - name: userId in: query - name: userId - type: string - - description: Page number + description: Filter by user ID + schema: + type: string + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.NotificationRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.NotificationRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List notifications + - KeycloakOAuth: [] + /v2/notifications/{notificationId}: + get: tags: - Notification - /v2/notifications/{notificationId}: - delete: - consumes: - - application/json - description: Delete notification + summary: Get notification + description: Get notification parameters: - - description: Notification ID + - name: notificationId in: path - name: notificationId + description: Notification ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/body.NotificationRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete notification + - KeycloakOAuth: [] + post: tags: - Notification - get: - consumes: - - application/json - description: Get notification + summary: Update notification + description: Update notification parameters: - - description: Notification ID + - name: notificationId in: path - name: notificationId + description: Notification ID + required: true + schema: + type: string + requestBody: + description: Notification update + content: + application/json: + schema: + $ref: '#/components/schemas/body.NotificationUpdate' required: true - type: string - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.NotificationRead' + content: {} "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get notification + - KeycloakOAuth: [] + x-codegen-request-body-name: body + delete: tags: - Notification - post: - consumes: - - application/json - description: Update notification + summary: Delete notification + description: Delete notification parameters: - - description: Notification ID + - name: notificationId in: path - name: notificationId - required: true - type: string - - description: Notification update - in: body - name: body + description: Notification ID required: true schema: - $ref: '#/definitions/body.NotificationUpdate' - produces: - - application/json + type: string responses: "200": description: OK + content: {} "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Update notification - tags: - - Notification + - KeycloakOAuth: [] /v2/register: get: - consumes: - - application/json + tags: + - Register + summary: Register resource description: Register resource - produces: - - application/json responses: "204": description: No Content + content: {} "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: Register resource - tags: - - Register + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/resourceMigrations: get: - consumes: - - application/json + tags: + - ResourceMigration + summary: List resource migrations description: List resource migrations parameters: - - description: Page number + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.ResourceMigrationRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.ResourceMigrationRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List resource migrations + - KeycloakOAuth: [] + post: tags: - ResourceMigration - post: - consumes: - - application/json + summary: Create resource migration description: Create resource migration - parameters: - - description: Resource Migration Create - in: body - name: body + requestBody: + description: Resource Migration Create + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationCreate' required: true - schema: - $ref: '#/definitions/body.ResourceMigrationCreate' - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.ResourceMigrationCreated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationCreated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Create resource migration + - KeycloakOAuth: [] + x-codegen-request-body-name: body + /v2/resourceMigrations/{resourceMigrationId}: + get: tags: - ResourceMigration - /v2/resourceMigrations/{resourceMigrationId}: - delete: - consumes: - - application/json - description: Delete resource migration + summary: Get resource migration + description: Get resource migration parameters: - - description: Resource Migration ID + - name: resourceMigrationId in: path - name: resourceMigrationId + description: Resource Migration ID required: true - type: string - produces: - - application/json + schema: + type: string responses: - "204": - description: No Content + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete resource migration + - KeycloakOAuth: [] + post: tags: - ResourceMigration - get: - consumes: - - application/json - description: Get resource migration + summary: Update resource migration + description: Update resource migration parameters: - - description: Resource Migration ID + - name: resourceMigrationId in: path - name: resourceMigrationId + description: Resource Migration ID + required: true + schema: + type: string + requestBody: + description: Resource Migration Update + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationUpdate' required: true - type: string - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.ResourceMigrationRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationUpdated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get resource migration + - KeycloakOAuth: [] + x-codegen-request-body-name: body + delete: tags: - ResourceMigration - post: - consumes: - - application/json - description: Update resource migration + summary: Delete resource migration + description: Delete resource migration parameters: - - description: Resource Migration ID + - name: resourceMigrationId in: path - name: resourceMigrationId - required: true - type: string - - description: Resource Migration Update - in: body - name: body + description: Resource Migration ID required: true schema: - $ref: '#/definitions/body.ResourceMigrationUpdate' - produces: - - application/json + type: string responses: - "200": - description: OK - schema: - $ref: '#/definitions/body.ResourceMigrationUpdated' + "204": + description: No Content + content: {} "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Update resource migration - tags: - - ResourceMigration + - KeycloakOAuth: [] /v2/snapshots: get: - consumes: - - application/json + tags: + - Snapshot + summary: List snapshots description: List snapshots parameters: - - description: Filter by VM ID + - name: vmId in: path - name: vmId + description: Filter by VM ID required: true - type: string - - description: Page number + schema: + type: string + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.VmSnapshotRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.VmSnapshotRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "423": description: Locked - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List snapshots + - KeycloakOAuth: [] + post: tags: - Snapshot - post: - consumes: - - application/json + summary: Create snapshot description: Create snapshot parameters: - - description: VM ID + - name: vmId in: path - name: vmId + description: VM ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmSnapshotCreated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmSnapshotCreated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Create snapshot - tags: - - Snapshot - /v2/status: - get: - consumes: - - application/json - description: List of worker status - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/body.WorkerStatusRead' - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: List worker status - tags: - - Status + - KeycloakOAuth: [] /v2/storageManagers: get: - consumes: - - application/json + tags: + - StorageManager + summary: Get storage manager list description: Get storage manager list parameters: - - description: List all + - name: all in: query - name: all - type: boolean - - description: Page number + description: List all + schema: + type: boolean + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.SmRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.SmRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get storage manager list - tags: - - StorageManager + - KeycloakOAuth: [] /v2/storageManagers/{storageManagerId}: get: - consumes: - - application/json + tags: + - StorageManager + summary: Delete storage manager description: Delete storage manager parameters: - - description: Storage manager ID + - name: storageManagerId in: path - name: storageManagerId + description: Storage manager ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.SmDeleted' + content: + application/json: + schema: + $ref: '#/components/schemas/body.SmDeleted' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete storage manager - tags: - - StorageManager + - KeycloakOAuth: [] /v2/systemCapacities: get: - consumes: - - application/json + tags: + - System + summary: List system capacities description: List system capacities parameters: - - description: "n" + - name: "n" in: query - name: "n" - type: integer - produces: - - application/json + description: "n" + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.TimestampedSystemCapacities' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.TimestampedSystemCapacities' "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: List system capacities - tags: - - System + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/systemStats: get: - consumes: - - application/json + tags: + - System + summary: List system stats description: List system stats parameters: - - description: "n" + - name: "n" in: query - name: "n" - type: integer - produces: - - application/json + description: "n" + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.TimestampedSystemCapacities' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.TimestampedSystemStats' "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: List system stats - tags: - - System + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/systemStatus: get: - consumes: - - application/json + tags: + - System + summary: List system stats description: List system stats parameters: - - description: "n" + - name: "n" in: query - name: "n" - type: integer - produces: - - application/json + description: "n" + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.TimestampedSystemCapacities' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.TimestampedSystemStatus' "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' - summary: List system stats - tags: - - System + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/teams: get: - consumes: - - application/json + tags: + - Team + summary: List teams description: List teams parameters: - - description: List all + - name: all in: query - name: all - type: boolean - - description: Filter by user ID + description: List all + schema: + type: boolean + - name: userId in: query - name: userId - type: string - - description: Page number + description: Filter by user ID + schema: + type: string + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.TeamRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.TeamRead' "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List teams + - KeycloakOAuth: [] + post: tags: - Team - post: - consumes: - - application/json + summary: Create team description: Create team - parameters: - - description: Team - in: body - name: body + requestBody: + description: Team + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamCreate' required: true - schema: - $ref: '#/definitions/body.TeamCreate' - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.TeamRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamRead' "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Create team + - KeycloakOAuth: [] + x-codegen-request-body-name: body + /v2/teams/{teamId}: + get: tags: - Team - /v2/teams/{teamId}: - delete: - consumes: - - application/json - description: Delete team + summary: Get team + description: Get team parameters: - - description: Team ID + - name: teamId in: path - name: teamId + description: Team ID required: true - type: string - produces: - - application/json + schema: + type: string responses: - "204": - description: No Content + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamRead' "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete team + - KeycloakOAuth: [] + post: tags: - Team - get: - consumes: - - application/json - description: Get team + summary: Update team + description: Update team parameters: - - description: Team ID + - name: teamId in: path - name: teamId + description: Team ID + required: true + schema: + type: string + requestBody: + description: Team + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamUpdate' required: true - type: string - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.TeamRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamRead' "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get team + - KeycloakOAuth: [] + x-codegen-request-body-name: body + delete: tags: - Team - post: - consumes: - - application/json - description: Update team + summary: Delete team + description: Delete team parameters: - - description: Team ID + - name: teamId in: path - name: teamId - required: true - type: string - - description: Team - in: body - name: body + description: Team ID required: true schema: - $ref: '#/definitions/body.TeamUpdate' - produces: - - application/json + type: string responses: - "200": - description: OK - schema: - $ref: '#/definitions/body.TeamRead' + "204": + description: No Content + content: {} "400": description: Bad Request - schema: - $ref: '#/definitions/body.BindingError' + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Update team - tags: - - Team + - KeycloakOAuth: [] /v2/users: get: - consumes: - - application/json + tags: + - User + summary: List users description: List users parameters: - - description: List all + - name: all in: query - name: all - type: boolean - - description: Discovery mode + description: List all + schema: + type: boolean + - name: discover in: query - name: discover - type: boolean - - description: Search query + description: Discovery mode + schema: + type: boolean + - name: search in: query - name: search - type: string - - description: Page number + description: Search query + schema: + type: string + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.UserRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.UserRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List users - tags: - - User + - KeycloakOAuth: [] /v2/users/{userId}: get: - consumes: - - application/json + tags: + - User + summary: Get user description: Get user parameters: - - description: User ID + - name: userId in: path - name: userId + description: User ID required: true - type: string - produces: - - application/json + schema: + type: string + - name: discover + in: query + description: Discovery mode + schema: + type: boolean responses: "200": description: OK - schema: - $ref: '#/definitions/body.UserRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.UserRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get user + - KeycloakOAuth: [] + post: tags: - User - post: - consumes: - - application/json + summary: Update user description: Update user parameters: - - description: User ID + - name: userId in: path - name: userId - required: true - type: string - - description: User update - in: body - name: body + description: User ID required: true schema: - $ref: '#/definitions/body.UserUpdate' - produces: - - application/json + type: string + requestBody: + description: User update + content: + application/json: + schema: + $ref: '#/components/schemas/body.UserUpdate' + required: true responses: "200": description: OK - schema: - $ref: '#/definitions/body.UserRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.UserRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Update user - tags: - - User + - KeycloakOAuth: [] + x-codegen-request-body-name: body /v2/users/{userId}/apiKeys: post: - consumes: - - application/json + tags: + - User + summary: Create API key description: Create API key parameters: - - description: User ID + - name: userId in: path - name: userId - required: true - type: string - - description: API key create body - in: body - name: body + description: User ID required: true schema: - $ref: '#/definitions/body.ApiKeyCreate' - produces: - - application/json + type: string + requestBody: + description: API key create body + content: + application/json: + schema: + $ref: '#/components/schemas/body.ApiKeyCreate' + required: true responses: "200": description: OK - schema: - $ref: '#/definitions/body.ApiKeyCreated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.ApiKeyCreated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Create API key - tags: - - User + - KeycloakOAuth: [] + x-codegen-request-body-name: body /v2/vmActions: post: - consumes: - - application/json + tags: + - VmAction + summary: Creates a new action description: Creates a new action parameters: - - description: VM ID + - name: vmId in: path - name: vmId - required: true - type: string - - description: actions body - in: body - name: body + description: VM ID required: true schema: - $ref: '#/definitions/body.VmActionCreate' - produces: - - application/json + type: string + requestBody: + description: actions body + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmActionCreate' + required: true responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmActionCreated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmActionCreated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Creates a new action - tags: - - VmAction + - KeycloakOAuth: [] + x-codegen-request-body-name: body /v2/vms: get: - consumes: - - application/json + tags: + - VM + summary: List VMs description: List VMs parameters: - - description: List all + - name: all in: query - name: all - type: boolean - - description: Filter by user ID + description: List all + schema: + type: boolean + - name: userId in: query - name: userId - type: string - - description: Page number + description: Filter by user ID + schema: + type: string + - name: page in: query - name: page - type: integer - - description: Number of items per page + description: Page number + schema: + type: integer + - name: pageSize in: query - name: pageSize - type: integer - produces: - - application/json + description: Number of items per page + schema: + type: integer responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.VmRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.VmRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List VMs + - KeycloakOAuth: [] + post: tags: - VM - post: - consumes: - - application/json + summary: Create VM description: Create VM - parameters: - - description: VM body - in: body - name: body + requestBody: + description: VM body + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmCreate' required: true - schema: - $ref: '#/definitions/body.VmCreate' - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmCreated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmCreated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Create VM + - KeycloakOAuth: [] + x-codegen-request-body-name: body + /v2/vms/{vmId}: + get: tags: - VM - /v2/vms/{vmId}: - delete: - consumes: - - application/json - description: Delete VM + summary: Get VM + description: Get VM parameters: - - description: VM ID + - name: vmId in: path - name: vmId + description: VM ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmDeleted' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' - "401": - description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete VM + - KeycloakOAuth: [] + post: tags: - VM - get: - consumes: - - application/json - description: Get VM + summary: Update VM + description: Update VM parameters: - - description: VM ID + - name: vmId in: path - name: vmId + description: VM ID + required: true + schema: + type: string + requestBody: + description: VM update + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmUpdate' required: true - type: string - produces: - - application/json responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmUpdated' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get VM + - KeycloakOAuth: [] + x-codegen-request-body-name: body + delete: tags: - VM - post: - consumes: - - application/json - description: Update VM + summary: Delete VM + description: Delete VM parameters: - - description: VM ID + - name: vmId in: path - name: vmId - required: true - type: string - - description: VM update - in: body - name: body + description: VM ID required: true schema: - $ref: '#/definitions/body.VmUpdate' - produces: - - application/json + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmUpdated' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmDeleted' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "401": description: Unauthorized - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Update VM - tags: - - VM + - KeycloakOAuth: [] /v2/vms/{vmId}/snapshot/{snapshotId}: - delete: - consumes: - - application/json - description: Delete snapshot + post: + tags: + - Snapshot + summary: Get snapshot + description: Get snapshot parameters: - - description: VM ID + - name: vmId in: path - name: vmId + description: VM ID required: true - type: string - - description: Snapshot ID + schema: + type: string + - name: snapshotId in: path - name: snapshotId + description: Snapshot ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmSnapshotDeleted' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmSnapshotRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Delete snapshot + - KeycloakOAuth: [] + delete: tags: - Snapshot - post: - consumes: - - application/json - description: Get snapshot + summary: Delete snapshot + description: Delete snapshot parameters: - - description: VM ID + - name: vmId in: path - name: vmId + description: VM ID required: true - type: string - - description: Snapshot ID + schema: + type: string + - name: snapshotId in: path - name: snapshotId + description: Snapshot ID required: true - type: string - produces: - - application/json + schema: + type: string responses: "200": description: OK - schema: - $ref: '#/definitions/body.VmSnapshotRead' + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmSnapshotDeleted' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "404": description: Not Found - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: Get snapshot + - KeycloakOAuth: [] + /v2/workerStatus: + get: tags: - - Snapshot + - Status + summary: List worker status + description: List of worker status + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.WorkerStatusRead' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' /v2/zones: get: - consumes: - - application/json + tags: + - Zone + summary: List zones description: List zones - produces: - - application/json responses: "200": description: OK - schema: - items: - $ref: '#/definitions/body.ZoneRead' - type: array + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/body.ZoneRead' "400": description: Bad Request - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' "500": description: Internal Server Error - schema: - $ref: '#/definitions/sys.ErrorResponse' + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' security: - ApiKeyAuth: [] - summary: List zones - tags: - - Zone -securityDefinitions: - ApiKeyAuth: - in: header - name: X-Api-Key - type: apiKey -swagger: "2.0" + - KeycloakOAuth: [] +components: + schemas: + body.ApiKey: + type: object + properties: + createdAt: + type: string + expiresAt: + type: string + name: + type: string + body.ApiKeyCreate: + required: + - expiresAt + - name + type: object + properties: + expiresAt: + type: string + name: + type: string + body.ApiKeyCreated: + type: object + properties: + createdAt: + type: string + expiresAt: + type: string + key: + type: string + name: + type: string + body.BindingError: + type: object + properties: + validationErrors: + type: object + additionalProperties: + type: array + items: + type: string + body.CiConfig: + type: object + properties: + config: + type: string + body.ClusterCapacities: + type: object + properties: + cluster: + type: string + cpuCore: + $ref: '#/components/schemas/body.CpuCoreCapacities' + gpu: + $ref: '#/components/schemas/body.GpuCapacities' + ram: + $ref: '#/components/schemas/body.RamCapacities' + body.ClusterStats: + type: object + properties: + cluster: + type: string + podCount: + type: integer + body.CpuCoreCapacities: + type: object + properties: + total: + type: integer + body.CpuStatus: + type: object + properties: + load: + $ref: '#/components/schemas/body.CpuStatusLoad' + temp: + $ref: '#/components/schemas/body.CpuStatusTemp' + body.CpuStatusLoad: + type: object + properties: + cores: + type: array + items: + type: integer + main: + type: number + max: + type: number + body.CpuStatusTemp: + type: object + properties: + cores: + type: array + items: + type: integer + main: + type: number + max: + type: number + body.CustomDomainRead: + type: object + properties: + domain: + type: string + secret: + type: string + status: + type: string + url: + type: string + body.DeploymentCommand: + required: + - command + type: object + properties: + command: + type: string + enum: + - restart + body.DeploymentCreate: + required: + - name + type: object + properties: + args: + maxItems: 100 + minItems: 0 + type: array + items: + type: string + cpuCores: + minimum: 0.1 + type: number + customDomain: + type: string + description: |- + CustomDomain is the domain that the deployment will be available on. + The max length is set to 243 to allow for a subdomain when confirming the domain. + envs: + maxItems: 1000 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.Env' + healthCheckPath: + maxLength: 1000 + minLength: 0 + type: string + image: + maxLength: 1000 + minLength: 1 + type: string + initCommands: + maxItems: 100 + minItems: 0 + type: array + items: + type: string + name: + maxLength: 30 + minLength: 3 + type: string + private: + type: boolean + description: "Deprecated: Use Visibility instead." + ram: + minimum: 0.1 + type: number + replicas: + maximum: 100 + minimum: 0 + type: integer + visibility: + type: string + enum: + - public + - private + - auth + volumes: + maxItems: 100 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.Volume' + zone: + type: string + description: |- + Zone is the zone that the deployment will be created in. + If the zone is not set, the deployment will be created in the default zone. + body.DeploymentCreated: + type: object + properties: + id: + type: string + jobId: + type: string + body.DeploymentRead: + type: object + properties: + accessedAt: + type: string + args: + type: array + items: + type: string + createdAt: + type: string + customDomain: + $ref: '#/components/schemas/body.CustomDomainRead' + envs: + type: array + items: + $ref: '#/components/schemas/body.Env' + error: + type: string + healthCheckPath: + type: string + id: + type: string + image: + type: string + initCommands: + type: array + items: + type: string + integrations: + type: array + description: |- + Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment + + For example GitHub + items: + type: string + internalPort: + type: integer + name: + type: string + ownerId: + type: string + pingResult: + type: integer + private: + type: boolean + description: "Deprecated: Use Visibility instead." + repairedAt: + type: string + replicaStatus: + $ref: '#/components/schemas/body.ReplicaStatus' + restartedAt: + type: string + specs: + $ref: '#/components/schemas/body.DeploymentSpecs' + status: + type: string + storageUrl: + type: string + teams: + type: array + items: + type: string + type: + type: string + updatedAt: + type: string + url: + type: string + visibility: + type: string + volumes: + type: array + items: + $ref: '#/components/schemas/body.Volume' + zone: + type: string + body.DeploymentSpecs: + type: object + properties: + cpuCores: + type: number + ram: + type: number + replicas: + type: integer + body.DeploymentUpdate: + required: + - name + type: object + properties: + args: + maxItems: 100 + minItems: 0 + type: array + items: + type: string + cpuCores: + minimum: 0.1 + type: number + customDomain: + type: string + description: |- + CustomDomain is the domain that the deployment will be available on. + The max length is set to 243 to allow for a subdomain when confirming the domain. + envs: + maxItems: 1000 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.Env' + healthCheckPath: + maxLength: 1000 + minLength: 0 + type: string + image: + maxLength: 1000 + minLength: 1 + type: string + initCommands: + maxItems: 100 + minItems: 0 + type: array + items: + type: string + name: + maxLength: 30 + minLength: 3 + type: string + private: + type: boolean + description: "Deprecated: Use Visibility instead." + ram: + minimum: 0.1 + type: number + replicas: + maximum: 100 + minimum: 0 + type: integer + visibility: + type: string + enum: + - public + - private + - auth + volumes: + maxItems: 100 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.Volume' + body.DeploymentUpdated: + type: object + properties: + id: + type: string + jobId: + type: string + body.DiscoverRead: + type: object + properties: + roles: + type: array + items: + $ref: '#/components/schemas/body.Role' + version: + type: string + body.Env: + required: + - name + - value + type: object + properties: + name: + maxLength: 100 + minLength: 1 + type: string + value: + maxLength: 10000 + minLength: 1 + type: string + body.GpuCapacities: + type: object + properties: + total: + type: integer + body.GpuGroupRead: + type: object + properties: + available: + type: integer + displayName: + type: string + id: + type: string + name: + type: string + total: + type: integer + vendor: + type: string + zone: + type: string + body.GpuLeaseCreate: + required: + - gpuGroupId + type: object + properties: + gpuGroupId: + type: string + description: |- + GpuGroupID is used to specify the GPU to lease. + As such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease. + leaseForever: + type: boolean + description: LeaseForever is used to specify whether the lease should be + created forever. + body.GpuLeaseCreated: + type: object + properties: + id: + type: string + jobId: + type: string + body.GpuLeaseDeleted: + type: object + properties: + id: + type: string + jobId: + type: string + body.GpuLeaseRead: + type: object + properties: + activatedAt: + type: string + description: |- + ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU + or 1 day after the lease was created if the user did not attach the GPU. + active: + type: boolean + assignedAt: + type: string + description: AssignedAt specifies the time when the lease was assigned to + the user. + createdAt: + type: string + expiredAt: + type: string + expiresAt: + type: string + description: |- + ExpiresAt specifies the time when the lease will expire. + This is only present if the lease is active. + gpuGroupId: + type: string + id: + type: string + leaseDuration: + type: number + queuePosition: + type: integer + userId: + type: string + vmId: + type: string + description: VmID is set when the lease is attached to a VM. + body.GpuLeaseUpdate: + type: object + properties: + vmId: + type: string + description: |- + VmID is used to specify the VM to attach the lease to. + + - If specified, the lease will be attached to the VM. + + - If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM. + + - If the lease is not active, specifying a VM will activate the lease. + + - If the lease is not assigned, an error will be returned. + body.GpuLeaseUpdated: + type: object + properties: + id: + type: string + jobId: + type: string + body.GpuStatus: + type: object + properties: + temp: + type: array + items: + $ref: '#/components/schemas/body.GpuStatusTemp' + body.GpuStatusTemp: + type: object + properties: + main: + type: number + body.HarborWebhook: + type: object + properties: + event_data: + type: object + properties: + repository: + type: object + properties: + date_created: + type: integer + name: + type: string + namespace: + type: string + repo_full_name: + type: string + repo_type: + type: string + resources: + type: array + items: + type: object + properties: + digest: + type: string + resource_url: + type: string + tag: + type: string + occur_at: + type: integer + operator: + type: string + type: + type: string + body.HostCapacities: + type: object + properties: + cpuCore: + $ref: '#/components/schemas/body.CpuCoreCapacities' + displayName: + type: string + gpu: + $ref: '#/components/schemas/body.GpuCapacities' + name: + type: string + ram: + $ref: '#/components/schemas/body.RamCapacities' + zone: + type: string + description: Zone is the name of the zone where the host is located. + body.HostRead: + type: object + properties: + displayName: + type: string + name: + type: string + zone: + type: string + description: Zone is the name of the zone where the host is located. + body.HostStatus: + type: object + properties: + cpu: + $ref: '#/components/schemas/body.CpuStatus' + displayName: + type: string + gpu: + $ref: '#/components/schemas/body.GpuStatus' + name: + type: string + ram: + $ref: '#/components/schemas/body.RamStatus' + zone: + type: string + description: Zone is the name of the zone where the host is located. + body.HttpProxyCreate: + required: + - name + type: object + properties: + customDomain: + type: string + description: |- + CustomDomain is the domain that the deployment will be available on. + The max length is set to 243 to allow for a subdomain when confirming the domain. + name: + maxLength: 30 + minLength: 3 + type: string + body.HttpProxyRead: + type: object + properties: + customDomain: + $ref: '#/components/schemas/body.CustomDomainRead' + name: + type: string + url: + type: string + body.HttpProxyUpdate: + required: + - name + type: object + properties: + customDomain: + type: string + description: |- + CustomDomain is the domain that the deployment will be available on. + The max length is set to 243 to allow for a subdomain when confirming the domain. + name: + maxLength: 30 + minLength: 3 + type: string + body.JobRead: + type: object + properties: + createdAt: + type: string + finishedAt: + type: string + id: + type: string + lastError: + type: string + lastRunAt: + type: string + runAfter: + type: string + status: + type: string + type: + type: string + userId: + type: string + body.JobUpdate: + type: object + properties: + status: + type: string + enum: + - pending + - running + - failed + - terminated + - finished + - completed + body.K8sStats: + type: object + properties: + clusters: + type: array + items: + $ref: '#/components/schemas/body.ClusterStats' + podCount: + type: integer + body.NotificationRead: + type: object + properties: + completedAt: + type: string + content: + type: object + additionalProperties: true + createdAt: + type: string + id: + type: string + readAt: + type: string + toastedAt: + type: string + type: + type: string + userId: + type: string + body.NotificationUpdate: + type: object + properties: + read: + type: boolean + toasted: + type: boolean + body.PortCreate: + required: + - name + - port + - protocol + type: object + properties: + httpProxy: + $ref: '#/components/schemas/body.HttpProxyCreate' + name: + maxLength: 100 + minLength: 1 + type: string + port: + maximum: 65535 + minimum: 1 + type: integer + protocol: + type: string + enum: + - tcp + - udp + body.PortRead: + type: object + properties: + externalPort: + type: integer + httpProxy: + $ref: '#/components/schemas/body.HttpProxyRead' + name: + type: string + port: + type: integer + protocol: + type: string + body.PortUpdate: + required: + - name + - port + - protocol + type: object + properties: + httpProxy: + $ref: '#/components/schemas/body.HttpProxyUpdate' + name: + maxLength: 100 + minLength: 1 + type: string + port: + maximum: 65535 + minimum: 1 + type: integer + protocol: + type: string + enum: + - tcp + - udp + body.PublicKey: + required: + - key + - name + type: object + properties: + key: + type: string + name: + maxLength: 30 + minLength: 1 + type: string + body.Quota: + type: object + properties: + cpuCores: + type: number + diskSize: + type: number + gpuLeaseDuration: + type: number + description: in hours + ram: + type: number + snapshots: + type: integer + body.RamCapacities: + type: object + properties: + total: + type: integer + body.RamStatus: + type: object + properties: + load: + $ref: '#/components/schemas/body.RamStatusLoad' + body.RamStatusLoad: + type: object + properties: + main: + type: number + body.ReplicaStatus: + type: object + properties: + availableReplicas: + type: integer + description: AvailableReplicas is the number of replicas that are available. + desiredReplicas: + type: integer + description: DesiredReplicas is the number of replicas that the deployment + should have. + readyReplicas: + type: integer + description: ReadyReplicas is the number of replicas that are ready. + unavailableReplicas: + type: integer + description: UnavailableReplicas is the number of replicas that are unavailable. + body.ResourceMigrationCreate: + required: + - resourceId + - type + type: object + properties: + resourceId: + type: string + description: |- + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. + status: + type: string + description: |- + Status is the status of the resource migration. + It is used by privileged admins to directly accept or reject a migration. + The field is ignored by non-admins. + + Possible values: + - accepted + - pending + type: + type: string + description: |- + Type is the type of the resource migration. + + Possible values: + - updateOwner + enum: + - updateOwner + updateOwner: + required: + - ownerId + type: object + properties: + ownerId: + type: string + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is ignored if the migration type is not updateOwner. + body.ResourceMigrationCreated: + type: object + properties: + createdAt: + type: string + deletedAt: + type: string + id: + type: string + jobId: + type: string + description: |- + JobID is the ID of the job that was created for the resource migration. + It will only be set if the migration was created with status 'accepted'. + resourceId: + type: string + description: |- + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. + resourceType: + type: string + description: |- + ResourceType is the type of the resource that is being migrated. + + Possible values: + - vm + - deployment + status: + type: string + description: |- + Status is the status of the resource migration. + When this field is set to 'accepted', the migration will take place and then automatically be deleted. + type: + type: string + description: |- + Type is the type of the resource migration. + + Possible values: + - updateOwner + updateOwner: + type: object + properties: + ownerId: + type: string + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is empty if the migration type is not updateOwner. + userId: + type: string + description: UserID is the ID of the user who initiated the migration. + body.ResourceMigrationRead: + type: object + properties: + createdAt: + type: string + deletedAt: + type: string + id: + type: string + resourceId: + type: string + description: |- + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. + resourceType: + type: string + description: |- + ResourceType is the type of the resource that is being migrated. + + Possible values: + - vm + - deployment + status: + type: string + description: |- + Status is the status of the resource migration. + When this field is set to 'accepted', the migration will take place and then automatically be deleted. + type: + type: string + description: |- + Type is the type of the resource migration. + + Possible values: + - updateOwner + updateOwner: + type: object + properties: + ownerId: + type: string + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is empty if the migration type is not updateOwner. + userId: + type: string + description: UserID is the ID of the user who initiated the migration. + body.ResourceMigrationUpdate: + required: + - status + type: object + properties: + code: + type: string + description: |- + Code is a token required when accepting a migration if the acceptor is not an admin. + It is sent to the acceptor using the notification API + status: + type: string + description: |- + Status is the status of the resource migration. + It is used to accept a migration by setting the status to 'accepted'. + If the acceptor is not an admin, a Code must be provided. + + Possible values: + - accepted + - pending + body.ResourceMigrationUpdated: + type: object + properties: + createdAt: + type: string + deletedAt: + type: string + id: + type: string + jobId: + type: string + description: |- + JobID is the ID of the job that was created for the resource migration. + It will only be set if the migration was updated with status 'accepted'. + resourceId: + type: string + description: |- + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. + resourceType: + type: string + description: |- + ResourceType is the type of the resource that is being migrated. + + Possible values: + - vm + - deployment + status: + type: string + description: |- + Status is the status of the resource migration. + When this field is set to 'accepted', the migration will take place and then automatically be deleted. + type: + type: string + description: |- + Type is the type of the resource migration. + + Possible values: + - updateOwner + updateOwner: + type: object + properties: + ownerId: + type: string + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is empty if the migration type is not updateOwner. + userId: + type: string + description: UserID is the ID of the user who initiated the migration. + body.Role: + type: object + properties: + description: + type: string + name: + type: string + permissions: + type: array + items: + type: string + quota: + $ref: '#/components/schemas/body.Quota' + body.SmDeleted: + type: object + properties: + id: + type: string + jobId: + type: string + body.SmRead: + type: object + properties: + createdAt: + type: string + id: + type: string + ownerId: + type: string + url: + type: string + zone: + type: string + body.SystemCapacities: + type: object + properties: + clusters: + type: array + description: Per Cluster + items: + $ref: '#/components/schemas/body.ClusterCapacities' + cpuCore: + type: object + description: Total + allOf: + - $ref: '#/components/schemas/body.CpuCoreCapacities' + gpu: + $ref: '#/components/schemas/body.GpuCapacities' + hosts: + type: array + description: Per Host + items: + $ref: '#/components/schemas/body.HostCapacities' + ram: + $ref: '#/components/schemas/body.RamCapacities' + body.SystemStats: + type: object + properties: + k8s: + $ref: '#/components/schemas/body.K8sStats' + body.SystemStatus: + type: object + properties: + hosts: + type: array + items: + $ref: '#/components/schemas/body.HostStatus' + body.TeamCreate: + required: + - name + type: object + properties: + description: + maxLength: 1000 + type: string + members: + maxItems: 100 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.TeamMemberCreate' + name: + maxLength: 100 + minLength: 1 + type: string + resources: + maxItems: 100 + minItems: 0 + type: array + items: + type: string + body.TeamMember: + type: object + properties: + addedAt: + type: string + email: + type: string + firstName: + type: string + gravatarUrl: + type: string + id: + type: string + joinedAt: + type: string + lastName: + type: string + memberStatus: + type: string + teamRole: + type: string + username: + type: string + body.TeamMemberCreate: + required: + - id + type: object + properties: + id: + type: string + teamRole: + type: string + description: default to MemberRoleAdmin right now + body.TeamMemberUpdate: + required: + - id + type: object + properties: + id: + type: string + teamRole: + type: string + description: default to MemberRoleAdmin right now + body.TeamRead: + type: object + properties: + createdAt: + type: string + description: + type: string + id: + type: string + members: + type: array + items: + $ref: '#/components/schemas/body.TeamMember' + name: + type: string + ownerId: + type: string + resources: + type: array + items: + $ref: '#/components/schemas/body.TeamResource' + updatedAt: + type: string + body.TeamResource: + type: object + properties: + id: + type: string + name: + type: string + type: + type: string + body.TeamUpdate: + type: object + properties: + description: + maxLength: 1000 + type: string + members: + maxItems: 100 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.TeamMemberUpdate' + name: + maxLength: 100 + minLength: 1 + type: string + resources: + maxItems: 100 + minItems: 0 + type: array + items: + type: string + body.TimestampedSystemCapacities: + type: object + properties: + capacities: + $ref: '#/components/schemas/body.SystemCapacities' + timestamp: + type: string + body.TimestampedSystemStats: + type: object + properties: + stats: + $ref: '#/components/schemas/body.SystemStats' + timestamp: + type: string + body.TimestampedSystemStatus: + type: object + properties: + status: + $ref: '#/components/schemas/body.SystemStatus' + timestamp: + type: string + body.Usage: + type: object + properties: + cpuCores: + type: number + diskSize: + type: integer + ram: + type: number + body.UserData: + required: + - key + - value + type: object + properties: + key: + maxLength: 255 + minLength: 1 + type: string + value: + maxLength: 255 + minLength: 1 + type: string + body.UserRead: + type: object + properties: + admin: + type: boolean + apiKeys: + type: array + items: + $ref: '#/components/schemas/body.ApiKey' + email: + type: string + firstName: + type: string + gravatarUrl: + type: string + id: + type: string + lastName: + type: string + publicKeys: + type: array + items: + $ref: '#/components/schemas/body.PublicKey' + quota: + $ref: '#/components/schemas/body.Quota' + role: + $ref: '#/components/schemas/body.Role' + storageUrl: + type: string + usage: + $ref: '#/components/schemas/body.Usage' + userData: + type: array + items: + $ref: '#/components/schemas/body.UserData' + username: + type: string + body.UserUpdate: + type: object + properties: + apiKeys: + maxItems: 100 + minItems: 0 + type: array + description: |- + ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted. + However, API keys cannot be created, use /apiKeys endpoint to create new API keys. + items: + $ref: '#/components/schemas/body.ApiKey' + publicKeys: + maxItems: 100 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.PublicKey' + userData: + maxItems: 100 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.UserData' + body.VmActionCreate: + required: + - action + type: object + properties: + action: + type: string + enum: + - start + - stop + - restart + - repair + body.VmActionCreated: + type: object + properties: + id: + type: string + jobId: + type: string + body.VmCreate: + required: + - cpuCores + - diskSize + - name + - ram + - sshPublicKey + type: object + properties: + cpuCores: + minimum: 1 + type: integer + diskSize: + minimum: 10 + type: integer + name: + maxLength: 30 + minLength: 3 + type: string + ports: + maxItems: 10 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.PortCreate' + ram: + minimum: 1 + type: integer + sshPublicKey: + type: string + zone: + type: string + body.VmCreated: + type: object + properties: + id: + type: string + jobId: + type: string + body.VmDeleted: + type: object + properties: + id: + type: string + jobId: + type: string + body.VmGpuLease: + type: object + properties: + activatedAt: + type: string + description: |- + ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU + or 1 day after the lease was created if the user did not attach the GPU. + assignedAt: + type: string + description: AssignedAt specifies the time when the lease was assigned to + the user. + createdAt: + type: string + expiredAt: + type: string + description: |- + ExpiredAt specifies the time when the lease expired. + This is only present if the lease is expired. + expiresAt: + type: string + description: |- + ExpiresAt specifies the time when the lease will expire. + This is only present if the lease is active. + gpuGroupId: + type: string + id: + type: string + leaseDuration: + type: number + body.VmRead: + type: object + properties: + accessedAt: + type: string + createdAt: + type: string + gpu: + $ref: '#/components/schemas/body.VmGpuLease' + host: + type: string + id: + type: string + internalName: + type: string + name: + type: string + ownerId: + type: string + ports: + type: array + items: + $ref: '#/components/schemas/body.PortRead' + repairedAt: + type: string + specs: + $ref: '#/components/schemas/body.VmSpecs' + sshConnectionString: + type: string + sshPublicKey: + type: string + status: + type: string + teams: + type: array + items: + type: string + updatedAt: + type: string + zone: + type: string + body.VmSnapshotCreated: + type: object + properties: + id: + type: string + jobId: + type: string + body.VmSnapshotDeleted: + type: object + properties: + id: + type: string + jobId: + type: string + body.VmSnapshotRead: + type: object + properties: + created: + type: string + id: + type: string + name: + type: string + status: + type: string + body.VmSpecs: + type: object + properties: + cpuCores: + type: integer + diskSize: + type: integer + ram: + type: integer + body.VmUpdate: + type: object + properties: + cpuCores: + minimum: 1 + type: integer + name: + maxLength: 30 + minLength: 3 + type: string + ports: + maxItems: 10 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/body.PortUpdate' + ram: + minimum: 1 + type: integer + body.VmUpdated: + type: object + properties: + id: + type: string + jobId: + type: string + body.Volume: + required: + - appPath + - name + - serverPath + type: object + properties: + appPath: + maxLength: 255 + minLength: 1 + type: string + name: + maxLength: 30 + minLength: 3 + type: string + serverPath: + maxLength: 255 + minLength: 1 + type: string + body.WorkerStatusRead: + type: object + properties: + name: + type: string + reportedAt: + type: string + status: + type: string + body.ZoneEndpoints: + type: object + properties: + deployment: + type: string + storage: + type: string + vm: + type: string + vmApp: + type: string + body.ZoneRead: + type: object + properties: + capabilities: + type: array + items: + type: string + description: + type: string + enabled: + type: boolean + endpoints: + $ref: '#/components/schemas/body.ZoneEndpoints' + legacy: + type: boolean + name: + type: string + sys.Error: + type: object + properties: + code: + type: string + msg: + type: string + sys.ErrorResponse: + type: object + properties: + errors: + type: array + items: + $ref: '#/components/schemas/sys.Error' + securitySchemes: + ApiKeyAuth: + type: apiKey + name: X-Api-Key + in: header + KeycloakOAuth: + type: oauth2 + flows: + authorizationCode: + authorizationUrl: https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth + tokenUrl: https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token + scopes: + email: email + openid: openid + profile: profile +x-original-swagger-version: "2.0" diff --git a/export/tygo.yml b/export/tygo.yml index ba322e51..ed1afbfb 100644 --- a/export/tygo.yml +++ b/export/tygo.yml @@ -1,14 +1,14 @@ packages: # v2 - - path: go-deploy/dto/v2/body + - path: github.com/kthcloud/go-deploy/dto/v2/body output_path: types/v2/body type_mappings: time.Time: "string" - - path: go-deploy/dto/v2/query + - path: github.com/kthcloud/go-deploy/dto/v2/query output_path: types/v2/query type_mappings: time.Time: "string" - - path: go-deploy/dto/v2/uri + - path: github.com/kthcloud/go-deploy/dto/v2/uri output_path: types/v2/uri type_mappings: time.Time: "string" diff --git a/export/types/v2/body/index.ts b/export/types/v2/body/index.ts index bf9b344f..6bfbacd6 100644 --- a/export/types/v2/body/index.ts +++ b/export/types/v2/body/index.ts @@ -40,11 +40,15 @@ export interface DeploymentRead { volumes: Volume[]; initCommands: string[]; args: string[]; - private: boolean; internalPort: number /* int */; image?: string; healthCheckPath?: string; customDomain?: CustomDomainRead; + visibility: string; + /** + * Deprecated: Use Visibility instead. + */ + private: boolean; status: string; error?: string; replicaStatus?: ReplicaStatus; @@ -62,11 +66,15 @@ export interface DeploymentCreate { cpuCores?: number /* float64 */; ram?: number /* float64 */; replicas?: number /* int */; - private: boolean; envs: Env[]; volumes: Volume[]; initCommands: string[]; args: string[]; + visibility: string; + /** + * Deprecated: Use Visibility instead. + */ + private: boolean; image?: string; healthCheckPath?: string; /** @@ -85,11 +93,15 @@ export interface DeploymentUpdate { cpuCores?: number /* float64 */; ram?: number /* float64 */; replicas?: number /* int */; - private?: boolean; envs?: Env[]; volumes?: Volume[]; initCommands?: string[]; args?: string[]; + visibility?: string; + /** + * Deprecated: Use Visibility instead. + */ + private?: boolean; image?: string; healthCheckPath?: string; /** @@ -292,6 +304,14 @@ export interface HostRegisterParams { * Token is the discovery token validated against the config */ token: string; + /** + * Enabled is the flag to enable or disable the node + */ + enabled: boolean; + /** + * Schedulable is the flag to enable or disable scheduling on the node + */ + schedulable: boolean; } ////////// @@ -322,10 +342,12 @@ export interface NotificationRead { content: { [key: string]: any}; createdAt: string; readAt?: string; + toastedAt?: string; completedAt?: string; } export interface NotificationUpdate { read: boolean; + toasted: boolean; } ////////// @@ -493,31 +515,36 @@ export interface TimestampedSystemCapacities { timestamp: string; } export interface SystemCapacities { + /** + * Total + */ cpuCore: CpuCoreCapacities; ram: RamCapacities; gpu: GpuCapacities; + /** + * Per Host + */ hosts: HostCapacities[]; + /** + * Per Cluster + */ + clusters: ClusterCapacities[]; } export interface ClusterCapacities { cluster: string; - ram: RamCapacities; cpuCore: CpuCoreCapacities; -} -export interface HostGpuCapacities { - count: number /* int */; -} -export interface HostRamCapacities { - total: number /* int */; + ram: RamCapacities; + gpu: GpuCapacities; } export interface HostCapacities extends HostBase { cpuCore: CpuCoreCapacities; - ram: HostRamCapacities; - gpu: HostGpuCapacities; + ram: RamCapacities; + gpu: GpuCapacities; } -export interface RamCapacities { +export interface CpuCoreCapacities { total: number /* int */; } -export interface CpuCoreCapacities { +export interface RamCapacities { total: number /* int */; } export interface GpuCapacities { @@ -750,20 +777,10 @@ export interface VmCreate { zone?: string; } export interface VmUpdate { + name?: string; ports?: PortUpdate[]; cpuCores?: number /* int */; ram?: number /* int */; - /** - * Name is used to rename a VM. - * If specified, only name will be updated. - */ - name?: string; - /** - * OwnerID is used to initiate transfer a VM to another user. - * If specified, only the transfer will happen. - * If specified but empty, the transfer will be canceled. - */ - ownerId?: string; } export interface VmUpdateOwner { newOwnerId: string; diff --git a/export/types/v2/query/index.ts b/export/types/v2/query/index.ts index f26a9683..bf860ee9 100644 --- a/export/types/v2/query/index.ts +++ b/export/types/v2/query/index.ts @@ -123,6 +123,9 @@ export interface TimestampRequest { ////////// // source: user.go +export interface UserGet { + Discover: boolean; +} export interface UserList { Pagination?: Pagination; All: boolean; diff --git a/main.go b/main.go index 9e7e9120..24a43088 100644 --- a/main.go +++ b/main.go @@ -1,8 +1,9 @@ package main import ( - "github.com/kthcloud/go-deploy/cmd" "os" + + "github.com/kthcloud/go-deploy/cmd" ) // @Title go-deploy API @@ -16,6 +17,12 @@ import ( // @SecurityDefinitions.apikey ApiKeyAuth // @In header // @Name X-Api-Key +// @SecurityDefinitions.oauth2.accessCode KeycloakOAuth +// @authorizationUrl https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth +// @tokenUrl https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token +// @scope.openid openid +// @scope.profile profile +// @scope.email email func main() { options := cmd.ParseFlags() diff --git a/routers/api/v2/api_key.go b/routers/api/v2/api_key.go index 529bf74d..8ca25d0c 100644 --- a/routers/api/v2/api_key.go +++ b/routers/api/v2/api_key.go @@ -2,6 +2,7 @@ package v2 import ( "errors" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/dto/v2/uri" @@ -17,6 +18,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param userId path string true "User ID" // @Param body body body.ApiKeyCreate true "API key create body" // @Success 200 {object} body.ApiKeyCreated diff --git a/routers/api/v2/deployment.go b/routers/api/v2/deployment.go index d0be0c31..7cdecf4d 100644 --- a/routers/api/v2/deployment.go +++ b/routers/api/v2/deployment.go @@ -2,6 +2,9 @@ package v2 import ( "errors" + "strconv" + "strings" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" @@ -17,8 +20,6 @@ import ( "github.com/kthcloud/go-deploy/service/v2/deployments/opts" teamOpts "github.com/kthcloud/go-deploy/service/v2/teams/opts" v12 "github.com/kthcloud/go-deploy/service/v2/utils" - "strconv" - "strings" ) // GetDeployment @@ -28,6 +29,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param deploymentId path string true "Deployment ID" // @Success 200 {object} body.DeploymentRead // @Failure 400 {object} sys.ErrorResponse @@ -84,6 +86,7 @@ func GetDeployment(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all" // @Param userId query string false "Filter by user ID" // @Param shared query bool false "Include shared" @@ -148,6 +151,7 @@ func ListDeployments(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param body body body.DeploymentCreate true "Deployment body" // @Success 200 {object} body.DeploymentRead // @Failure 400 {object} sys.ErrorResponse @@ -249,6 +253,7 @@ func CreateDeployment(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param deploymentId path string true "Deployment ID" // @Success 200 {object} body.DeploymentCreated // @Failure 400 {object} sys.ErrorResponse @@ -330,6 +335,7 @@ func DeleteDeployment(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param deploymentId path string true "Deployment ID" // @Param body body body.DeploymentUpdate true "Deployment update" // @Success 200 {object} body.DeploymentUpdated diff --git a/routers/api/v2/deployment_ci_config.go b/routers/api/v2/deployment_ci_config.go index 5ed6cb8c..0976b81d 100644 --- a/routers/api/v2/deployment_ci_config.go +++ b/routers/api/v2/deployment_ci_config.go @@ -2,12 +2,13 @@ package v2 import ( "errors" + "net/http" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/uri" "github.com/kthcloud/go-deploy/pkg/sys" "github.com/kthcloud/go-deploy/service" dErrors "github.com/kthcloud/go-deploy/service/errors" - "net/http" ) // GetCiConfig @@ -17,6 +18,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param deploymentId path string true "Deployment ID" // @Success 200 {object} body.CiConfig // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/deployment_command.go b/routers/api/v2/deployment_command.go index 99cd65b5..402e4d0d 100644 --- a/routers/api/v2/deployment_command.go +++ b/routers/api/v2/deployment_command.go @@ -16,6 +16,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param deploymentId path string true "Deployment ID" // @Param body body body.DeploymentCommand true "Command body" // @Success 204 "No Content" diff --git a/routers/api/v2/deployment_logs.go b/routers/api/v2/deployment_logs.go index 512e3aee..679f416f 100644 --- a/routers/api/v2/deployment_logs.go +++ b/routers/api/v2/deployment_logs.go @@ -3,6 +3,9 @@ package v2 import ( "context" "errors" + "io" + "time" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/dto/v2/uri" @@ -10,8 +13,6 @@ import ( "github.com/kthcloud/go-deploy/service" errors2 "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/v2/deployments" - "io" - "time" ) // GetLogs @@ -21,6 +22,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param deploymentId path string true "Deployment ID" // @Success 200 {string} string // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/gpu_group.go b/routers/api/v2/gpu_group.go index 290bd911..757ab8a7 100644 --- a/routers/api/v2/gpu_group.go +++ b/routers/api/v2/gpu_group.go @@ -18,6 +18,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param gpuGroupId path string true "GPU group ID" // @Success 200 {object} body.GpuGroupRead // @Failure 400 {object} sys.ErrorResponse @@ -71,6 +72,7 @@ func GetGpuGroup(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param page query int false "Page number" // @Param pageSize query int false "Number of items per page" // @Success 200 {array} body.GpuGroupRead diff --git a/routers/api/v2/gpu_lease.go b/routers/api/v2/gpu_lease.go index 98dbb932..1ffa12b5 100644 --- a/routers/api/v2/gpu_lease.go +++ b/routers/api/v2/gpu_lease.go @@ -2,6 +2,7 @@ package v2 import ( "errors" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" @@ -23,6 +24,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param gpuLeaseId path string true "GPU lease ID" // @Success 200 {object} body.GpuLeaseRead // @Failure 400 {object} sys.ErrorResponse @@ -75,6 +77,7 @@ func GetGpuLease(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all" // @Param vmId query string false "Filter by VM ID" // @Param page query int false "Page number" @@ -152,6 +155,7 @@ func ListGpuLeases(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param body body body.GpuLeaseCreate true "GPU lease" // @Success 200 {object} body.GpuLeaseCreated // @Failure 400 {object} sys.ErrorResponse @@ -239,6 +243,7 @@ func CreateGpuLease(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param gpuLeaseId path string true "GPU lease ID" // @Param body body body.GpuLeaseUpdate true "GPU lease" // @Success 200 {object} body.GpuLeaseUpdated @@ -310,6 +315,7 @@ func UpdateGpuLease(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param gpuLeaseId path string true "GPU lease ID" // @Success 200 {object} body.GpuLeaseDeleted // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/job.go b/routers/api/v2/job.go index ca5574ab..94592ba0 100644 --- a/routers/api/v2/job.go +++ b/routers/api/v2/job.go @@ -2,6 +2,7 @@ package v2 import ( "errors" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/dto/v2/query" @@ -22,6 +23,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param jobId path string true "Job ID" // @Success 200 {object} body.JobRead // @Failure 400 {object} sys.ErrorResponse @@ -65,6 +67,7 @@ func GetJob(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all" // @Param userId query string false "Filter by user ID" // @Param type query string false "Filter by type" @@ -123,6 +126,7 @@ func ListJobs(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param jobId path string true "Job ID" // @Param body body body.JobUpdate true "Job update" // @Success 200 {object} body.JobRead diff --git a/routers/api/v2/notification.go b/routers/api/v2/notification.go index c0015654..a5e2dc51 100644 --- a/routers/api/v2/notification.go +++ b/routers/api/v2/notification.go @@ -2,6 +2,8 @@ package v2 import ( "errors" + "net/http" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/dto/v2/query" @@ -11,7 +13,6 @@ import ( sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/v2/notifications/opts" v12 "github.com/kthcloud/go-deploy/service/v2/utils" - "net/http" ) // GetNotification godoc @@ -21,6 +22,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param notificationId path string true "Notification ID" // @Success 200 {object} body.NotificationRead // @Failure 400 {object} sys.ErrorResponse @@ -56,6 +58,7 @@ func GetNotification(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all notifications" // @Param userId query string false "Filter by user ID" // @Param page query int false "Page number" @@ -109,6 +112,7 @@ func ListNotifications(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param notificationId path string true "Notification ID" // @Param body body body.NotificationUpdate true "Notification update" // @Success 200 @@ -156,6 +160,7 @@ func UpdateNotification(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param notificationId path string true "Notification ID" // @Success 200 // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/resource_migration.go b/routers/api/v2/resource_migration.go index d5f42882..6be1d140 100644 --- a/routers/api/v2/resource_migration.go +++ b/routers/api/v2/resource_migration.go @@ -2,6 +2,8 @@ package v2 import ( "errors" + "net/http" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" @@ -11,7 +13,6 @@ import ( "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/v2/resource_migrations/opts" - "net/http" ) // GetResourceMigration @@ -21,6 +22,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param resourceMigrationId path string true "Resource Migration ID" // @Success 200 {object} body.ResourceMigrationRead // @Failure 400 {object} sys.ErrorResponse @@ -63,6 +65,7 @@ func GetResourceMigration(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param page query int false "Page number" // @Param pageSize query int false "Number of items per page" // @Success 200 {array} body.ResourceMigrationRead @@ -111,6 +114,7 @@ func ListResourceMigrations(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param body body body.ResourceMigrationCreate true "Resource Migration Create" // @Success 200 {object} body.ResourceMigrationCreated // @Failure 400 {object} sys.ErrorResponse @@ -177,6 +181,7 @@ func CreateResourceMigration(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param resourceMigrationId path string true "Resource Migration ID" // @Param body body body.ResourceMigrationUpdate true "Resource Migration Update" // @Success 200 {object} body.ResourceMigrationUpdated @@ -277,6 +282,7 @@ func UpdateResourceMigration(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param resourceMigrationId path string true "Resource Migration ID" // @Success 204 "No Content" // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/sm.go b/routers/api/v2/sm.go index 6ae410ac..7b3e408c 100644 --- a/routers/api/v2/sm.go +++ b/routers/api/v2/sm.go @@ -1,6 +1,10 @@ package v2 import ( + "net/http" + "strconv" + "strings" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" @@ -14,9 +18,6 @@ import ( "github.com/kthcloud/go-deploy/service" "github.com/kthcloud/go-deploy/service/v2/sms/opts" v12 "github.com/kthcloud/go-deploy/service/v2/utils" - "net/http" - "strconv" - "strings" ) // GetSM @@ -26,6 +27,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param storageManagerId path string true "Storage manager ID" // @Success 200 {object} body.SmDeleted // @Failure 400 {object} sys.ErrorResponse @@ -69,6 +71,7 @@ func GetSM(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all" // @Param page query int false "Page number" // @Param pageSize query int false "Number of items per page" @@ -122,6 +125,7 @@ func ListSMs(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param storageManagerId path string true "Storage manager ID" // @Success 200 {object} body.SmDeleted // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/snapshot.go b/routers/api/v2/snapshot.go index cc685add..0ece241b 100644 --- a/routers/api/v2/snapshot.go +++ b/routers/api/v2/snapshot.go @@ -2,6 +2,7 @@ package v2 import ( "errors" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" @@ -23,6 +24,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "VM ID" // @Param snapshotId path string true "Snapshot ID" // @Success 200 {object} body.VmSnapshotRead @@ -83,6 +85,7 @@ func GetSnapshot(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "Filter by VM ID" // @Param page query int false "Page number" // @Param pageSize query int false "Number of items per page" @@ -139,6 +142,7 @@ func ListSnapshots(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "VM ID" // @Success 200 {object} body.VmSnapshotCreated // @Failure 400 {object} sys.ErrorResponse @@ -240,6 +244,7 @@ func CreateSnapshot(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "VM ID" // @Param snapshotId path string true "Snapshot ID" // @Success 200 {object} body.VmSnapshotDeleted diff --git a/routers/api/v2/team.go b/routers/api/v2/team.go index de28bbb6..6ba3bff5 100644 --- a/routers/api/v2/team.go +++ b/routers/api/v2/team.go @@ -3,6 +3,9 @@ package v2 import ( "errors" "fmt" + "net/http" + "time" + "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/google/uuid" @@ -18,8 +21,6 @@ import ( v12 "github.com/kthcloud/go-deploy/service/v2/utils" vmOpts "github.com/kthcloud/go-deploy/service/v2/vms/opts" "github.com/kthcloud/go-deploy/utils" - "net/http" - "time" ) // GetTeam @@ -29,6 +30,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param teamId path string true "Team ID" // @Success 200 {object} body.TeamRead // @Failure 400 {object} body.BindingError @@ -65,6 +67,7 @@ func GetTeam(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all" // @Param userId query string false "Filter by user ID" // @Param page query int false "Page number" @@ -119,6 +122,7 @@ func ListTeams(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param body body body.TeamCreate true "Team" // @Success 200 {object} body.TeamRead // @Failure 400 {object} body.BindingError @@ -160,6 +164,7 @@ func CreateTeam(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param teamId path string true "Team ID" // @Param body body body.TeamUpdate true "Team" // @Success 200 {object} body.TeamRead @@ -219,6 +224,7 @@ func UpdateTeam(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param teamId path string true "Team ID" // @Success 204 "No Content" // @Failure 400 {object} body.BindingError diff --git a/routers/api/v2/user.go b/routers/api/v2/user.go index 0f233241..43ec5ec8 100644 --- a/routers/api/v2/user.go +++ b/routers/api/v2/user.go @@ -2,6 +2,7 @@ package v2 import ( "errors" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/dto/v2/query" @@ -22,6 +23,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param userId path string true "User ID" // @Param discover query bool false "Discovery mode" // @Success 200 {object} body.UserRead @@ -101,6 +103,7 @@ func GetUser(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all" // @Param discover query bool false "Discovery mode" // @Param search query string false "Search query" @@ -173,6 +176,7 @@ func ListUsers(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param userId path string true "User ID" // @Param body body body.UserUpdate true "User update" // @Success 200 {object} body.UserRead diff --git a/routers/api/v2/vm.go b/routers/api/v2/vm.go index f1326a58..c375e056 100644 --- a/routers/api/v2/vm.go +++ b/routers/api/v2/vm.go @@ -2,6 +2,9 @@ package v2 import ( "errors" + "strconv" + "strings" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" @@ -17,8 +20,6 @@ import ( teamOpts "github.com/kthcloud/go-deploy/service/v2/teams/opts" v2Utils "github.com/kthcloud/go-deploy/service/v2/utils" "github.com/kthcloud/go-deploy/service/v2/vms/opts" - "strconv" - "strings" ) // GetVM @@ -28,6 +29,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "VM ID" // @Success 200 {object} body.VmRead // @Failure 400 {object} sys.ErrorResponse @@ -88,6 +90,7 @@ func GetVM(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param all query bool false "List all" // @Param userId query string false "Filter by user ID" // @Param page query int false "Page number" @@ -155,6 +158,7 @@ func ListVMs(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param body body body.VmCreate true "VM body" // @Success 200 {object} body.VmCreated // @Failure 400 {object} sys.ErrorResponse @@ -246,6 +250,7 @@ func CreateVM(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "VM ID" // @Success 200 {object} body.VmDeleted // @Failure 400 {object} sys.ErrorResponse @@ -309,6 +314,7 @@ func DeleteVM(c *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "VM ID" // @Param body body body.VmUpdate true "VM update" // @Success 200 {object} body.VmUpdated diff --git a/routers/api/v2/vm_action.go b/routers/api/v2/vm_action.go index 01d8f54c..f6bf859c 100644 --- a/routers/api/v2/vm_action.go +++ b/routers/api/v2/vm_action.go @@ -19,6 +19,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Param vmId path string true "VM ID" // @Param body body body.VmActionCreate true "actions body" // @Success 200 {object} body.VmActionCreated diff --git a/routers/api/v2/zone.go b/routers/api/v2/zone.go index 491434d3..62f5af97 100644 --- a/routers/api/v2/zone.go +++ b/routers/api/v2/zone.go @@ -15,6 +15,7 @@ import ( // @Accept json // @Produce json // @Security ApiKeyAuth +// @Security KeycloakOAuth // @Success 200 {array} body.ZoneRead // @Failure 400 {object} sys.ErrorResponse // @Failure 500 {object} sys.ErrorResponse From 31df7b6c6150a62cef609a42fb614c2120293ae0 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Wed, 15 Jan 2025 23:36:29 +0100 Subject: [PATCH 04/36] update tygo to use new module name --- export/tygo.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/export/tygo.yml b/export/tygo.yml index ba322e51..ed1afbfb 100644 --- a/export/tygo.yml +++ b/export/tygo.yml @@ -1,14 +1,14 @@ packages: # v2 - - path: go-deploy/dto/v2/body + - path: github.com/kthcloud/go-deploy/dto/v2/body output_path: types/v2/body type_mappings: time.Time: "string" - - path: go-deploy/dto/v2/query + - path: github.com/kthcloud/go-deploy/dto/v2/query output_path: types/v2/query type_mappings: time.Time: "string" - - path: go-deploy/dto/v2/uri + - path: github.com/kthcloud/go-deploy/dto/v2/uri output_path: types/v2/uri type_mappings: time.Time: "string" From 90e8348e202f4c12f9f2be0db18204a835c03054 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Thu, 16 Jan 2025 00:23:07 +0100 Subject: [PATCH 05/36] add makefile with targets to simplify building and running tests --- .gitignore | 1 + Makefile | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 0050e9a0..5dd6f429 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ cache/ kube/ # binary +bin go-deploy go-deploy.exe diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..d0498cb0 --- /dev/null +++ b/Makefile @@ -0,0 +1,57 @@ +# Variables +BINARY_NAME=go-deploy +BUILD_DIR=bin +MAIN_FILE=main.go +BUILDTIMESTAMP=$(shell date -u +%Y%m%d%H%M%S) +EXT=$(if $(filter windows,$(GOOS)),.exe,) + +# Targets +.PHONY: all clean build run clean docs release test acc e2e + +all: build + +build: + @echo "Building the application..." + @mkdir -p $(BUILD_DIR) + @CGO_ENABLED=0 go build -o $(BUILD_DIR)/$(BINARY_NAME)$(EXT) . + @echo "Build complete." + +run: build + @echo "Running the application..." + @./$(BUILD_DIR)/$(BINARY_NAME)$(EXT) + +clean: + @echo "Cleaning up..." + @rm -rf $(BUILD_DIR) + @echo "Clean complete." + +docs: + @cd scripts && ./generate-docs.sh && ./convert-to-v3-docs.sh && ./generate-types.sh + +release: docs + @echo "Building the application..." + @mkdir -p $(BUILD_DIR) + @CGO_ENABLED=0 go build -mod=readonly -ldflags "-w -s" -o $(BUILD_DIR)/$(BINARY_NAME)$(EXT) . + @echo "Build complete." + +test: clean build + @go test ./... + +acc: clean build + @go test ./test/acc/... + +e2e: clean build + @echo "Starting go-deploy in test mode..." + @./$(BUILD_DIR)/$(BINARY_NAME)$(EXT) --mode=test & echo $$! > go_deploy.pid + @echo "Waiting for API to become ready..." + @until curl --output /dev/null --silent --head --fail http://localhost:8080/healthz; do \ + echo "Waiting for API to start"; \ + sleep 1; \ + done + @echo "API is ready!" + @echo "Running e2e tests..." + @go test ./test/e2e/... + @if [ -f go_deploy.pid ]; then \ + echo "Stopping go-deploy..."; \ + kill $$(cat go_deploy.pid) && rm -f go_deploy.pid; \ + fi From 8d8906069721e1aa7b0202a9fbc2ee7b02f09f78 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 13:38:48 +0100 Subject: [PATCH 06/36] update docs to openapi 3.1.0 --- .github/workflows/build-docs.yml | 28 +- Makefile | 2 +- docs/api/v2/V2_docs.go | 5563 +--------------------- docs/api/v2/V2_swagger.json | 4486 +++++++++++++++++- docs/api/v2/V2_swagger.yaml | 7382 +++++++++++++++--------------- docs/api/v2/handlers/serve_fs.go | 52 + go.mod | 18 +- go.sum | 41 +- main.go | 3 + routers/router.go | 21 +- scripts/convert-to-v3-docs.sh | 29 - scripts/generate-docs.sh | 4 +- 12 files changed, 8402 insertions(+), 9227 deletions(-) create mode 100644 docs/api/v2/handlers/serve_fs.go delete mode 100755 scripts/convert-to-v3-docs.sh diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index e54bc427..7ed4024e 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -2,28 +2,24 @@ name: Build docs on: pull_request: - branches: [ "main" ] + branches: ["main"] paths: - "routers/**" - - '.github/workflows/build-docs.yml' + - ".github/workflows/build-docs.yml" jobs: build-docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v3 - - name: Build docs - run: | - cd scripts - source ./path-cmd.sh - - chmod +x ./generate-docs.sh - ./generate-docs.sh - - chmod +x ./convert-to-v3-docs.sh - ./convert-to-v3-docs.sh - - cd .. - \ No newline at end of file + - name: Build docs + run: | + cd scripts + source ./path-cmd.sh + + chmod +x ./generate-docs.sh + ./generate-docs.sh + + cd .. diff --git a/Makefile b/Makefile index d0498cb0..9499336e 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ clean: @echo "Clean complete." docs: - @cd scripts && ./generate-docs.sh && ./convert-to-v3-docs.sh && ./generate-types.sh + @cd scripts && ./generate-docs.sh && ./generate-types.sh release: docs @echo "Building the application..." diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index a94ad852..bc009def 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -1,5568 +1,21 @@ -// Package v2 Code generated by swaggo/swag. DO NOT EDIT +// Code generated by swaggo/swag. DO NOT EDIT. + package v2 -import "github.com/swaggo/swag" +import "github.com/swaggo/swag/v2" const docTemplateV2 = `{ "schemes": {{ marshal .Schemes }}, - "swagger": "2.0", - "info": { - "description": "{{escape .Description}}", - "title": "{{.Title}}", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "name": "Support", - "url": "https://github.com/kthcloud/go-deploy" - }, - "license": { - "name": "MIT License", - "url": "https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme" - }, - "version": "{{.Version}}" - }, - "host": "{{.Host}}", - "basePath": "{{.BasePath}}", - "paths": { - "/v2/deployments": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List deployments", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "List deployments", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "boolean", - "description": "Include shared", - "name": "shared", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.DeploymentRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Create deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Create deployment", - "parameters": [ - { - "description": "Deployment body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.DeploymentCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Get deployment", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Update deployment", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - }, - { - "description": "Deployment update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.DeploymentUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete deployment", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Delete deployment", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DeploymentCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}/ciConfig": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get CI config", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Get CI config", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.CiConfig" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}/command": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Do command", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Do command", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - }, - { - "description": "Command body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.DeploymentCommand" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/deployments/{deploymentId}/logs": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get logs using Server-Sent Events", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Get logs using Server-Sent Events", - "parameters": [ - { - "type": "string", - "description": "Deployment ID", - "name": "deploymentId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/discover": { - "get": { - "description": "Discover", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Discover" - ], - "summary": "Discover", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.DiscoverRead" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuGroups": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List GPU groups", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuGroup" - ], - "summary": "List GPU groups", - "parameters": [ - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.GpuGroupRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuGroups/{gpuGroupId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get GPU group", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuGroup" - ], - "summary": "Get GPU group", - "parameters": [ - { - "type": "string", - "description": "GPU group ID", - "name": "gpuGroupId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuGroupRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuLeases": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List GPU leases", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "List GPU leases", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by VM ID", - "name": "vmId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.GpuLeaseRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Create GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Create GPU Lease", - "parameters": [ - { - "description": "GPU lease", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.GpuLeaseCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/gpuLeases/{gpuLeaseId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Get GPU lease", - "parameters": [ - { - "type": "string", - "description": "GPU lease ID", - "name": "gpuLeaseId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Update GPU lease", - "parameters": [ - { - "type": "string", - "description": "GPU lease ID", - "name": "gpuLeaseId", - "in": "path", - "required": true - }, - { - "description": "GPU lease", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.GpuLeaseUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete GPU lease", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "GpuLease" - ], - "summary": "Delete GPU lease", - "parameters": [ - { - "type": "string", - "description": "GPU lease ID", - "name": "gpuLeaseId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.GpuLeaseDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/hooks/harbor": { - "post": { - "description": "Handle Harbor hook", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Deployment" - ], - "summary": "Handle Harbor hook", - "parameters": [ - { - "type": "string", - "description": "Basic auth token", - "name": "Authorization", - "in": "header" - }, - { - "description": "Harbor webhook body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.HarborWebhook" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/hosts": { - "get": { - "description": "List Hosts", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Host" - ], - "summary": "List Hosts", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.HostRead" - } - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/jobs": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List jobs", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Job" - ], - "summary": "List jobs", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "string", - "description": "Filter by type", - "name": "type", - "in": "query" - }, - { - "type": "string", - "description": "Filter by status", - "name": "status", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.JobRead" - } - } - } - } - } - }, - "/v2/jobs/{jobId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "GetJob job by id", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Job" - ], - "summary": "GetJob job by id", - "parameters": [ - { - "type": "string", - "description": "Job ID", - "name": "jobId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.JobRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update job. Only allowed for admins.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Job" - ], - "summary": "Update job", - "parameters": [ - { - "type": "string", - "description": "Job ID", - "name": "jobId", - "in": "path", - "required": true - }, - { - "description": "Job update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.JobUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.JobRead" - } - } - } - } - }, - "/v2/metrics": { - "get": { - "description": "Get metrics", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Get metrics", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/notifications": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List notifications", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "List notifications", - "parameters": [ - { - "type": "boolean", - "description": "List all notifications", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.NotificationRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/notifications/{notificationId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get notification", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "Get notification", - "parameters": [ - { - "type": "string", - "description": "Notification ID", - "name": "notificationId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.NotificationRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update notification", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "Update notification", - "parameters": [ - { - "type": "string", - "description": "Notification ID", - "name": "notificationId", - "in": "path", - "required": true - }, - { - "description": "Notification update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.NotificationUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete notification", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Notification" - ], - "summary": "Delete notification", - "parameters": [ - { - "type": "string", - "description": "Notification ID", - "name": "notificationId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/register": { - "get": { - "description": "Register resource", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Register" - ], - "summary": "Register resource", - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/resourceMigrations": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List resource migrations", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "List resource migrations", - "parameters": [ - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.ResourceMigrationRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Create resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Create resource migration", - "parameters": [ - { - "description": "Resource Migration Create", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.ResourceMigrationCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ResourceMigrationCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/resourceMigrations/{resourceMigrationId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Get resource migration", - "parameters": [ - { - "type": "string", - "description": "Resource Migration ID", - "name": "resourceMigrationId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ResourceMigrationRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Update resource migration", - "parameters": [ - { - "type": "string", - "description": "Resource Migration ID", - "name": "resourceMigrationId", - "in": "path", - "required": true - }, - { - "description": "Resource Migration Update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.ResourceMigrationUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ResourceMigrationUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete resource migration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "ResourceMigration" - ], - "summary": "Delete resource migration", - "parameters": [ - { - "type": "string", - "description": "Resource Migration ID", - "name": "resourceMigrationId", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/snapshots": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List snapshots", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "List snapshots", - "parameters": [ - { - "type": "string", - "description": "Filter by VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.VmSnapshotRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "423": { - "description": "Locked", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Create snapshot", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "Create snapshot", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmSnapshotCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/storageManagers": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get storage manager list", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "StorageManager" - ], - "summary": "Get storage manager list", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.SmRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/storageManagers/{storageManagerId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete storage manager", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "StorageManager" - ], - "summary": "Delete storage manager", - "parameters": [ - { - "type": "string", - "description": "Storage manager ID", - "name": "storageManagerId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.SmDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/systemCapacities": { - "get": { - "description": "List system capacities", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "System" - ], - "summary": "List system capacities", - "parameters": [ - { - "type": "integer", - "description": "n", - "name": "n", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TimestampedSystemCapacities" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/systemStats": { - "get": { - "description": "List system stats", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "System" - ], - "summary": "List system stats", - "parameters": [ - { - "type": "integer", - "description": "n", - "name": "n", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TimestampedSystemStats" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/systemStatus": { - "get": { - "description": "List system stats", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "System" - ], - "summary": "List system stats", - "parameters": [ - { - "type": "integer", - "description": "n", - "name": "n", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TimestampedSystemStatus" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/teams": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List teams", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "List teams", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TeamRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Create team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Create team", - "parameters": [ - { - "description": "Team", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.TeamCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.TeamRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/teams/{teamId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Get team", - "parameters": [ - { - "type": "string", - "description": "Team ID", - "name": "teamId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.TeamRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Update team", - "parameters": [ - { - "type": "string", - "description": "Team ID", - "name": "teamId", - "in": "path", - "required": true - }, - { - "description": "Team", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.TeamUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.TeamRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete team", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Team" - ], - "summary": "Delete team", - "parameters": [ - { - "type": "string", - "description": "Team ID", - "name": "teamId", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/body.BindingError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/users": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List users", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "List users", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "boolean", - "description": "Discovery mode", - "name": "discover", - "in": "query" - }, - { - "type": "string", - "description": "Search query", - "name": "search", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.UserRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/users/{userId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get user", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "Get user", - "parameters": [ - { - "type": "string", - "description": "User ID", - "name": "userId", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Discovery mode", - "name": "discover", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.UserRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update user", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "Update user", - "parameters": [ - { - "type": "string", - "description": "User ID", - "name": "userId", - "in": "path", - "required": true - }, - { - "description": "User update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.UserUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.UserRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/users/{userId}/apiKeys": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Create API key", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "User" - ], - "summary": "Create API key", - "parameters": [ - { - "type": "string", - "description": "User ID", - "name": "userId", - "in": "path", - "required": true - }, - { - "description": "API key create body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.ApiKeyCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.ApiKeyCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vmActions": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Creates a new action", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VmAction" - ], - "summary": "Creates a new action", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "description": "actions body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.VmActionCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmActionCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vms": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List VMs", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "List VMs", - "parameters": [ - { - "type": "boolean", - "description": "List all", - "name": "all", - "in": "query" - }, - { - "type": "string", - "description": "Filter by user ID", - "name": "userId", - "in": "query" - }, - { - "type": "integer", - "description": "Page number", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items per page", - "name": "pageSize", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.VmRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Create VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Create VM", - "parameters": [ - { - "description": "VM body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.VmCreate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmCreated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vms/{vmId}": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Get VM", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Update VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Update VM", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "description": "VM update", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/body.VmUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmUpdated" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete VM", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "VM" - ], - "summary": "Delete VM", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/vms/{vmId}/snapshot/{snapshotId}": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Get snapshot", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "Get snapshot", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Snapshot ID", - "name": "snapshotId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmSnapshotRead" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - }, - "delete": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "Delete snapshot", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Snapshot" - ], - "summary": "Delete snapshot", - "parameters": [ - { - "type": "string", - "description": "VM ID", - "name": "vmId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Snapshot ID", - "name": "snapshotId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/body.VmSnapshotDeleted" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/workerStatus": { - "get": { - "description": "List of worker status", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Status" - ], - "summary": "List worker status", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.WorkerStatusRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - }, - "/v2/zones": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - }, - { - "KeycloakOAuth": [] - } - ], - "description": "List zones", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Zone" - ], - "summary": "List zones", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/body.ZoneRead" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/sys.ErrorResponse" - } - } - } - } - } - }, - "definitions": { - "body.ApiKey": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "expiresAt": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "body.ApiKeyCreate": { - "type": "object", - "required": [ - "expiresAt", - "name" - ], - "properties": { - "expiresAt": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "body.ApiKeyCreated": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "expiresAt": { - "type": "string" - }, - "key": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "body.BindingError": { - "type": "object", - "properties": { - "validationErrors": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "body.CiConfig": { - "type": "object", - "properties": { - "config": { - "type": "string" - } - } - }, - "body.ClusterCapacities": { - "type": "object", - "properties": { - "cluster": { - "type": "string" - }, - "cpuCore": { - "$ref": "#/definitions/body.CpuCoreCapacities" - }, - "gpu": { - "$ref": "#/definitions/body.GpuCapacities" - }, - "ram": { - "$ref": "#/definitions/body.RamCapacities" - } - } - }, - "body.ClusterStats": { - "type": "object", - "properties": { - "cluster": { - "type": "string" - }, - "podCount": { - "type": "integer" - } - } - }, - "body.CpuCoreCapacities": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } - }, - "body.CpuStatus": { - "type": "object", - "properties": { - "load": { - "$ref": "#/definitions/body.CpuStatusLoad" - }, - "temp": { - "$ref": "#/definitions/body.CpuStatusTemp" - } - } - }, - "body.CpuStatusLoad": { - "type": "object", - "properties": { - "cores": { - "type": "array", - "items": { - "type": "integer" - } - }, - "main": { - "type": "number" - }, - "max": { - "type": "number" - } - } - }, - "body.CpuStatusTemp": { - "type": "object", - "properties": { - "cores": { - "type": "array", - "items": { - "type": "integer" - } - }, - "main": { - "type": "number" - }, - "max": { - "type": "number" - } - } - }, - "body.CustomDomainRead": { - "type": "object", - "properties": { - "domain": { - "type": "string" - }, - "secret": { - "type": "string" - }, - "status": { - "type": "string" - }, - "url": { - "type": "string" - } - } - }, - "body.DeploymentCommand": { - "type": "object", - "required": [ - "command" - ], - "properties": { - "command": { - "type": "string", - "enum": [ - "restart" - ] - } - } - }, - "body.DeploymentCreate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "args": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "cpuCores": { - "type": "number", - "minimum": 0.1 - }, - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "envs": { - "type": "array", - "maxItems": 1000, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Env" - } - }, - "healthCheckPath": { - "type": "string", - "maxLength": 1000, - "minLength": 0 - }, - "image": { - "type": "string", - "maxLength": 1000, - "minLength": 1 - }, - "initCommands": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "private": { - "description": "Deprecated: Use Visibility instead.", - "type": "boolean" - }, - "ram": { - "type": "number", - "minimum": 0.1 - }, - "replicas": { - "type": "integer", - "maximum": 100, - "minimum": 0 - }, - "visibility": { - "type": "string", - "enum": [ - "public", - "private", - "auth" - ] - }, - "volumes": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Volume" - } - }, - "zone": { - "description": "Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.", - "type": "string" - } - } - }, - "body.DeploymentCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.DeploymentRead": { - "type": "object", - "properties": { - "accessedAt": { - "type": "string" - }, - "args": { - "type": "array", - "items": { - "type": "string" - } - }, - "createdAt": { - "type": "string" - }, - "customDomain": { - "$ref": "#/definitions/body.CustomDomainRead" - }, - "envs": { - "type": "array", - "items": { - "$ref": "#/definitions/body.Env" - } - }, - "error": { - "type": "string" - }, - "healthCheckPath": { - "type": "string" - }, - "id": { - "type": "string" - }, - "image": { - "type": "string" - }, - "initCommands": { - "type": "array", - "items": { - "type": "string" - } - }, - "integrations": { - "description": "Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub", - "type": "array", - "items": { - "type": "string" - } - }, - "internalPort": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "pingResult": { - "type": "integer" - }, - "private": { - "description": "Deprecated: Use Visibility instead.", - "type": "boolean" - }, - "repairedAt": { - "type": "string" - }, - "replicaStatus": { - "$ref": "#/definitions/body.ReplicaStatus" - }, - "restartedAt": { - "type": "string" - }, - "specs": { - "$ref": "#/definitions/body.DeploymentSpecs" - }, - "status": { - "type": "string" - }, - "storageUrl": { - "type": "string" - }, - "teams": { - "type": "array", - "items": { - "type": "string" - } - }, - "type": { - "type": "string" - }, - "updatedAt": { - "type": "string" - }, - "url": { - "type": "string" - }, - "visibility": { - "type": "string" - }, - "volumes": { - "type": "array", - "items": { - "$ref": "#/definitions/body.Volume" - } - }, - "zone": { - "type": "string" - } - } - }, - "body.DeploymentSpecs": { - "type": "object", - "properties": { - "cpuCores": { - "type": "number" - }, - "ram": { - "type": "number" - }, - "replicas": { - "type": "integer" - } - } - }, - "body.DeploymentUpdate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "args": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "cpuCores": { - "type": "number", - "minimum": 0.1 - }, - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "envs": { - "type": "array", - "maxItems": 1000, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Env" - } - }, - "healthCheckPath": { - "type": "string", - "maxLength": 1000, - "minLength": 0 - }, - "image": { - "type": "string", - "maxLength": 1000, - "minLength": 1 - }, - "initCommands": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "private": { - "description": "Deprecated: Use Visibility instead.", - "type": "boolean" - }, - "ram": { - "type": "number", - "minimum": 0.1 - }, - "replicas": { - "type": "integer", - "maximum": 100, - "minimum": 0 - }, - "visibility": { - "type": "string", - "enum": [ - "public", - "private", - "auth" - ] - }, - "volumes": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.Volume" - } - } - } - }, - "body.DeploymentUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.DiscoverRead": { - "type": "object", - "properties": { - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/body.Role" - } - }, - "version": { - "type": "string" - } - } - }, - "body.Env": { - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "value": { - "type": "string", - "maxLength": 10000, - "minLength": 1 - } - } - }, - "body.GpuCapacities": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } - }, - "body.GpuGroupRead": { - "type": "object", - "properties": { - "available": { - "type": "integer" - }, - "displayName": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "total": { - "type": "integer" - }, - "vendor": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.GpuLeaseCreate": { - "type": "object", - "required": [ - "gpuGroupId" - ], - "properties": { - "gpuGroupId": { - "description": "GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.", - "type": "string" - }, - "leaseForever": { - "description": "LeaseForever is used to specify whether the lease should be created forever.", - "type": "boolean" - } - } - }, - "body.GpuLeaseCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.GpuLeaseDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.GpuLeaseRead": { - "type": "object", - "properties": { - "activatedAt": { - "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", - "type": "string" - }, - "active": { - "type": "boolean" - }, - "assignedAt": { - "description": "AssignedAt specifies the time when the lease was assigned to the user.", - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "expiredAt": { - "type": "string" - }, - "expiresAt": { - "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", - "type": "string" - }, - "gpuGroupId": { - "type": "string" - }, - "id": { - "type": "string" - }, - "leaseDuration": { - "type": "number" - }, - "queuePosition": { - "type": "integer" - }, - "userId": { - "type": "string" - }, - "vmId": { - "description": "VmID is set when the lease is attached to a VM.", - "type": "string" - } - } - }, - "body.GpuLeaseUpdate": { - "type": "object", - "properties": { - "vmId": { - "description": "VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.", - "type": "string" - } - } - }, - "body.GpuLeaseUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.GpuStatus": { - "type": "object", - "properties": { - "temp": { - "type": "array", - "items": { - "$ref": "#/definitions/body.GpuStatusTemp" - } - } - } - }, - "body.GpuStatusTemp": { - "type": "object", - "properties": { - "main": { - "type": "number" - } - } - }, - "body.HarborWebhook": { - "type": "object", - "properties": { - "event_data": { - "type": "object", - "properties": { - "repository": { - "type": "object", - "properties": { - "date_created": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "namespace": { - "type": "string" - }, - "repo_full_name": { - "type": "string" - }, - "repo_type": { - "type": "string" - } - } - }, - "resources": { - "type": "array", - "items": { - "type": "object", - "properties": { - "digest": { - "type": "string" - }, - "resource_url": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - } - } - } - }, - "occur_at": { - "type": "integer" - }, - "operator": { - "type": "string" - }, - "type": { - "type": "string" - } - } - }, - "body.HostCapacities": { - "type": "object", - "properties": { - "cpuCore": { - "$ref": "#/definitions/body.CpuCoreCapacities" - }, - "displayName": { - "type": "string" - }, - "gpu": { - "$ref": "#/definitions/body.GpuCapacities" - }, - "name": { - "type": "string" - }, - "ram": { - "$ref": "#/definitions/body.RamCapacities" - }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - } - }, - "body.HostRead": { - "type": "object", - "properties": { - "displayName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - } - }, - "body.HostStatus": { - "type": "object", - "properties": { - "cpu": { - "$ref": "#/definitions/body.CpuStatus" - }, - "displayName": { - "type": "string" - }, - "gpu": { - "$ref": "#/definitions/body.GpuStatus" - }, - "name": { - "type": "string" - }, - "ram": { - "$ref": "#/definitions/body.RamStatus" - }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - } - }, - "body.HttpProxyCreate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - } - } - }, - "body.HttpProxyRead": { - "type": "object", - "properties": { - "customDomain": { - "$ref": "#/definitions/body.CustomDomainRead" - }, - "name": { - "type": "string" - }, - "url": { - "type": "string" - } - } - }, - "body.HttpProxyUpdate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - } - } - }, - "body.JobRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "finishedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "lastError": { - "type": "string" - }, - "lastRunAt": { - "type": "string" - }, - "runAfter": { - "type": "string" - }, - "status": { - "type": "string" - }, - "type": { - "type": "string" - }, - "userId": { - "type": "string" - } - } - }, - "body.JobUpdate": { - "type": "object", - "properties": { - "status": { - "type": "string", - "enum": [ - "pending", - "running", - "failed", - "terminated", - "finished", - "completed" - ] - } - } - }, - "body.K8sStats": { - "type": "object", - "properties": { - "clusters": { - "type": "array", - "items": { - "$ref": "#/definitions/body.ClusterStats" - } - }, - "podCount": { - "type": "integer" - } - } - }, - "body.NotificationRead": { - "type": "object", - "properties": { - "completedAt": { - "type": "string" - }, - "content": { - "type": "object", - "additionalProperties": true - }, - "createdAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "readAt": { - "type": "string" - }, - "toastedAt": { - "type": "string" - }, - "type": { - "type": "string" - }, - "userId": { - "type": "string" - } - } - }, - "body.NotificationUpdate": { - "type": "object", - "properties": { - "read": { - "type": "boolean" - }, - "toasted": { - "type": "boolean" - } - } - }, - "body.PortCreate": { - "type": "object", - "required": [ - "name", - "port", - "protocol" - ], - "properties": { - "httpProxy": { - "$ref": "#/definitions/body.HttpProxyCreate" - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "port": { - "type": "integer", - "maximum": 65535, - "minimum": 1 - }, - "protocol": { - "type": "string", - "enum": [ - "tcp", - "udp" - ] - } - } - }, - "body.PortRead": { - "type": "object", - "properties": { - "externalPort": { - "type": "integer" - }, - "httpProxy": { - "$ref": "#/definitions/body.HttpProxyRead" - }, - "name": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "protocol": { - "type": "string" - } - } - }, - "body.PortUpdate": { - "type": "object", - "required": [ - "name", - "port", - "protocol" - ], - "properties": { - "httpProxy": { - "$ref": "#/definitions/body.HttpProxyUpdate" - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "port": { - "type": "integer", - "maximum": 65535, - "minimum": 1 - }, - "protocol": { - "type": "string", - "enum": [ - "tcp", - "udp" - ] - } - } - }, - "body.PublicKey": { - "type": "object", - "required": [ - "key", - "name" - ], - "properties": { - "key": { - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 1 - } - } - }, - "body.Quota": { - "type": "object", - "properties": { - "cpuCores": { - "type": "number" - }, - "diskSize": { - "type": "number" - }, - "gpuLeaseDuration": { - "description": "in hours", - "type": "number" - }, - "ram": { - "type": "number" - }, - "snapshots": { - "type": "integer" - } - } - }, - "body.RamCapacities": { - "type": "object", - "properties": { - "total": { - "type": "integer" - } - } - }, - "body.RamStatus": { - "type": "object", - "properties": { - "load": { - "$ref": "#/definitions/body.RamStatusLoad" - } - } - }, - "body.RamStatusLoad": { - "type": "object", - "properties": { - "main": { - "type": "number" - } - } - }, - "body.ReplicaStatus": { - "type": "object", - "properties": { - "availableReplicas": { - "description": "AvailableReplicas is the number of replicas that are available.", - "type": "integer" - }, - "desiredReplicas": { - "description": "DesiredReplicas is the number of replicas that the deployment should have.", - "type": "integer" - }, - "readyReplicas": { - "description": "ReadyReplicas is the number of replicas that are ready.", - "type": "integer" - }, - "unavailableReplicas": { - "description": "UnavailableReplicas is the number of replicas that are unavailable.", - "type": "integer" - } - } - }, - "body.ResourceMigrationCreate": { - "type": "object", - "required": [ - "resourceId", - "type" - ], - "properties": { - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string", - "enum": [ - "updateOwner" - ] - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.", - "type": "object", - "required": [ - "ownerId" - ], - "properties": { - "ownerId": { - "type": "string" - } - } - } - } - }, - "body.ResourceMigrationCreated": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "deletedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "jobId": { - "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.", - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "type": "object", - "properties": { - "ownerId": { - "type": "string" - } - } - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - } - }, - "body.ResourceMigrationRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "deletedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "type": "object", - "properties": { - "ownerId": { - "type": "string" - } - } - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - } - }, - "body.ResourceMigrationUpdate": { - "type": "object", - "required": [ - "status" - ], - "properties": { - "code": { - "description": "Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending", - "type": "string" - } - } - }, - "body.ResourceMigrationUpdated": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "deletedAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "jobId": { - "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.", - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "type": "object", - "properties": { - "ownerId": { - "type": "string" - } - } - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - } - }, - "body.Role": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "permissions": { - "type": "array", - "items": { - "type": "string" - } - }, - "quota": { - "$ref": "#/definitions/body.Quota" - } - } - }, - "body.SmDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.SmRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "id": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "url": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.SystemCapacities": { - "type": "object", - "properties": { - "clusters": { - "description": "Per Cluster", - "type": "array", - "items": { - "$ref": "#/definitions/body.ClusterCapacities" - } - }, - "cpuCore": { - "description": "Total", - "allOf": [ - { - "$ref": "#/definitions/body.CpuCoreCapacities" - } - ] - }, - "gpu": { - "$ref": "#/definitions/body.GpuCapacities" - }, - "hosts": { - "description": "Per Host", - "type": "array", - "items": { - "$ref": "#/definitions/body.HostCapacities" - } - }, - "ram": { - "$ref": "#/definitions/body.RamCapacities" - } - } - }, - "body.SystemStats": { - "type": "object", - "properties": { - "k8s": { - "$ref": "#/definitions/body.K8sStats" - } - } - }, - "body.SystemStatus": { - "type": "object", - "properties": { - "hosts": { - "type": "array", - "items": { - "$ref": "#/definitions/body.HostStatus" - } - } - } - }, - "body.TeamCreate": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "description": { - "type": "string", - "maxLength": 1000 - }, - "members": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.TeamMemberCreate" - } - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "resources": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - } - } - }, - "body.TeamMember": { - "type": "object", - "properties": { - "addedAt": { - "type": "string" - }, - "email": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "gravatarUrl": { - "type": "string" - }, - "id": { - "type": "string" - }, - "joinedAt": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "memberStatus": { - "type": "string" - }, - "teamRole": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "body.TeamMemberCreate": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - }, - "teamRole": { - "description": "default to MemberRoleAdmin right now", - "type": "string" - } - } - }, - "body.TeamMemberUpdate": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - }, - "teamRole": { - "description": "default to MemberRoleAdmin right now", - "type": "string" - } - } - }, - "body.TeamRead": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string" - }, - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TeamMember" - } - }, - "name": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "resources": { - "type": "array", - "items": { - "$ref": "#/definitions/body.TeamResource" - } - }, - "updatedAt": { - "type": "string" - } - } - }, - "body.TeamResource": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - } - }, - "body.TeamUpdate": { - "type": "object", - "properties": { - "description": { - "type": "string", - "maxLength": 1000 - }, - "members": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.TeamMemberUpdate" - } - }, - "name": { - "type": "string", - "maxLength": 100, - "minLength": 1 - }, - "resources": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "type": "string" - } - } - } - }, - "body.TimestampedSystemCapacities": { - "type": "object", - "properties": { - "capacities": { - "$ref": "#/definitions/body.SystemCapacities" - }, - "timestamp": { - "type": "string" - } - } - }, - "body.TimestampedSystemStats": { - "type": "object", - "properties": { - "stats": { - "$ref": "#/definitions/body.SystemStats" - }, - "timestamp": { - "type": "string" - } - } - }, - "body.TimestampedSystemStatus": { - "type": "object", - "properties": { - "status": { - "$ref": "#/definitions/body.SystemStatus" - }, - "timestamp": { - "type": "string" - } - } - }, - "body.Usage": { - "type": "object", - "properties": { - "cpuCores": { - "type": "number" - }, - "diskSize": { - "type": "integer" - }, - "ram": { - "type": "number" - } - } - }, - "body.UserData": { - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "type": "string", - "maxLength": 255, - "minLength": 1 - }, - "value": { - "type": "string", - "maxLength": 255, - "minLength": 1 - } - } - }, - "body.UserRead": { - "type": "object", - "properties": { - "admin": { - "type": "boolean" - }, - "apiKeys": { - "type": "array", - "items": { - "$ref": "#/definitions/body.ApiKey" - } - }, - "email": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "gravatarUrl": { - "type": "string" - }, - "id": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "publicKeys": { - "type": "array", - "items": { - "$ref": "#/definitions/body.PublicKey" - } - }, - "quota": { - "$ref": "#/definitions/body.Quota" - }, - "role": { - "$ref": "#/definitions/body.Role" - }, - "storageUrl": { - "type": "string" - }, - "usage": { - "$ref": "#/definitions/body.Usage" - }, - "userData": { - "type": "array", - "items": { - "$ref": "#/definitions/body.UserData" - } - }, - "username": { - "type": "string" - } - } - }, - "body.UserUpdate": { - "type": "object", - "properties": { - "apiKeys": { - "description": "ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.", - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.ApiKey" - } - }, - "publicKeys": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.PublicKey" - } - }, - "userData": { - "type": "array", - "maxItems": 100, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.UserData" - } - } - } - }, - "body.VmActionCreate": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string", - "enum": [ - "start", - "stop", - "restart", - "repair" - ] - } - } - }, - "body.VmActionCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmCreate": { - "type": "object", - "required": [ - "cpuCores", - "diskSize", - "name", - "ram", - "sshPublicKey" - ], - "properties": { - "cpuCores": { - "type": "integer", - "minimum": 1 - }, - "diskSize": { - "type": "integer", - "minimum": 10 - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "ports": { - "type": "array", - "maxItems": 10, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.PortCreate" - } - }, - "ram": { - "type": "integer", - "minimum": 1 - }, - "sshPublicKey": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.VmCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmGpuLease": { - "type": "object", - "properties": { - "activatedAt": { - "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", - "type": "string" - }, - "assignedAt": { - "description": "AssignedAt specifies the time when the lease was assigned to the user.", - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "expiredAt": { - "description": "ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.", - "type": "string" - }, - "expiresAt": { - "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", - "type": "string" - }, - "gpuGroupId": { - "type": "string" - }, - "id": { - "type": "string" - }, - "leaseDuration": { - "type": "number" - } - } - }, - "body.VmRead": { - "type": "object", - "properties": { - "accessedAt": { - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "gpu": { - "$ref": "#/definitions/body.VmGpuLease" - }, - "host": { - "type": "string" - }, - "id": { - "type": "string" - }, - "internalName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "ports": { - "type": "array", - "items": { - "$ref": "#/definitions/body.PortRead" - } - }, - "repairedAt": { - "type": "string" - }, - "specs": { - "$ref": "#/definitions/body.VmSpecs" - }, - "sshConnectionString": { - "type": "string" - }, - "sshPublicKey": { - "type": "string" - }, - "status": { - "type": "string" - }, - "teams": { - "type": "array", - "items": { - "type": "string" - } - }, - "updatedAt": { - "type": "string" - }, - "zone": { - "type": "string" - } - } - }, - "body.VmSnapshotCreated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmSnapshotDeleted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.VmSnapshotRead": { - "type": "object", - "properties": { - "created": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "status": { - "type": "string" - } - } - }, - "body.VmSpecs": { - "type": "object", - "properties": { - "cpuCores": { - "type": "integer" - }, - "diskSize": { - "type": "integer" - }, - "ram": { - "type": "integer" - } - } - }, - "body.VmUpdate": { - "type": "object", - "properties": { - "cpuCores": { - "type": "integer", - "minimum": 1 - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "ports": { - "type": "array", - "maxItems": 10, - "minItems": 0, - "items": { - "$ref": "#/definitions/body.PortUpdate" - } - }, - "ram": { - "type": "integer", - "minimum": 1 - } - } - }, - "body.VmUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "jobId": { - "type": "string" - } - } - }, - "body.Volume": { - "type": "object", - "required": [ - "appPath", - "name", - "serverPath" - ], - "properties": { - "appPath": { - "type": "string", - "maxLength": 255, - "minLength": 1 - }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 3 - }, - "serverPath": { - "type": "string", - "maxLength": 255, - "minLength": 1 - } - } - }, - "body.WorkerStatusRead": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "reportedAt": { - "type": "string" - }, - "status": { - "type": "string" - } - } - }, - "body.ZoneEndpoints": { - "type": "object", - "properties": { - "deployment": { - "type": "string" - }, - "storage": { - "type": "string" - }, - "vm": { - "type": "string" - }, - "vmApp": { - "type": "string" - } - } - }, - "body.ZoneRead": { - "type": "object", - "properties": { - "capabilities": { - "type": "array", - "items": { - "type": "string" - } - }, - "description": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "endpoints": { - "$ref": "#/definitions/body.ZoneEndpoints" - }, - "legacy": { - "type": "boolean" - }, - "name": { - "type": "string" - } - } - }, - "sys.Error": { - "type": "object", - "properties": { - "code": { - "type": "string" - }, - "msg": { - "type": "string" - } - } - }, - "sys.ErrorResponse": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "$ref": "#/definitions/sys.Error" - } - } - } - } - }, - "securityDefinitions": { - "ApiKeyAuth": { - "type": "apiKey", - "name": "X-Api-Key", - "in": "header" - }, - "KeycloakOAuth": { - "type": "oauth2", - "flow": "accessCode", - "authorizationUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth", - "tokenUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token", - "scopes": { - "email": "email", - "openid": "openid", - "profile": "profile" - } - } - } + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"{{escape .Description}}","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"{{.Title}}","version":"{{.Version}}"}, + "externalDocs": {"description":"","url":""}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"get":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "openapi": "3.1.0" }` // SwaggerInfoV2 holds exported Swagger Info so clients can modify it var SwaggerInfoV2 = &swag.Spec{ Version: "1.0", - Host: "", - BasePath: "", - Schemes: []string{}, Title: "go-deploy API", Description: "This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.", InfoInstanceName: "V2", diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index cd0954a7..f64173c7 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -1 +1,4485 @@ -{"openapi":"3.0.1","info":{"title":"go-deploy API","description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","termsOfService":"http://swagger.io/terms/","contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"version":"1.0"},"servers":[{"url":"/"}],"paths":{"/v2/deployments":{"get":{"tags":["Deployment"],"summary":"List deployments","description":"List deployments","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"shared","in":"query","description":"Include shared","schema":{"type":"boolean"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.DeploymentRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Deployment"],"summary":"Create deployment","description":"Create deployment","requestBody":{"description":"Deployment body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/deployments/{deploymentId}":{"get":{"tags":["Deployment"],"summary":"Get deployment","description":"Get deployment","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Deployment"],"summary":"Update deployment","description":"Update deployment","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Deployment update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["Deployment"],"summary":"Delete deployment","description":"Delete deployment","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"tags":["Deployment"],"summary":"Get CI config","description":"Get CI config","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/deployments/{deploymentId}/command":{"post":{"tags":["Deployment"],"summary":"Do command","description":"Do command","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Command body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"required":true},"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/deployments/{deploymentId}/logs":{"get":{"tags":["Deployment"],"summary":"Get logs using Server-Sent Events","description":"Get logs using Server-Sent Events","parameters":[{"name":"deploymentId","in":"path","description":"Deployment ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/discover":{"get":{"tags":["Discover"],"summary":"Discover","description":"Discover","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/gpuGroups":{"get":{"tags":["GpuGroup"],"summary":"List GPU groups","description":"List GPU groups","parameters":[{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.GpuGroupRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"tags":["GpuGroup"],"summary":"Get GPU group","description":"Get GPU group","parameters":[{"name":"gpuGroupId","in":"path","description":"GPU group ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/gpuLeases":{"get":{"tags":["GpuLease"],"summary":"List GPU leases","description":"List GPU leases","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"vmId","in":"query","description":"Filter by VM ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["GpuLease"],"summary":"Create GPU Lease","description":"Create GPU lease","requestBody":{"description":"GPU lease","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/gpuLeases/{gpuLeaseId}":{"get":{"tags":["GpuLease"],"summary":"Get GPU lease","description":"Get GPU lease","parameters":[{"name":"gpuLeaseId","in":"path","description":"GPU lease ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["GpuLease"],"summary":"Update GPU lease","description":"Update GPU lease","parameters":[{"name":"gpuLeaseId","in":"path","description":"GPU lease ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"GPU lease","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["GpuLease"],"summary":"Delete GPU lease","description":"Delete GPU lease","parameters":[{"name":"gpuLeaseId","in":"path","description":"GPU lease ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/hooks/harbor":{"post":{"tags":["Deployment"],"summary":"Handle Harbor hook","description":"Handle Harbor hook","parameters":[{"name":"Authorization","in":"header","description":"Basic auth token","schema":{"type":"string"}}],"requestBody":{"description":"Harbor webhook body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"required":true},"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"x-codegen-request-body-name":"body"}},"/v2/hosts":{"get":{"tags":["Host"],"summary":"List Hosts","description":"List Hosts","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.HostRead"}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/jobs":{"get":{"tags":["Job"],"summary":"List jobs","description":"List jobs","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"type","in":"query","description":"Filter by type","schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by status","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.JobRead"}}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/jobs/{jobId}":{"get":{"tags":["Job"],"summary":"GetJob job by id","description":"GetJob job by id","parameters":[{"name":"jobId","in":"path","description":"Job ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Job"],"summary":"Update job","description":"Update job. Only allowed for admins.","parameters":[{"name":"jobId","in":"path","description":"Job ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Job update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/metrics":{"get":{"tags":["Metrics"],"summary":"Get metrics","description":"Get metrics","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/notifications":{"get":{"tags":["Notification"],"summary":"List notifications","description":"List notifications","parameters":[{"name":"all","in":"query","description":"List all notifications","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.NotificationRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/notifications/{notificationId}":{"get":{"tags":["Notification"],"summary":"Get notification","description":"Get notification","parameters":[{"name":"notificationId","in":"path","description":"Notification ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Notification"],"summary":"Update notification","description":"Update notification","parameters":[{"name":"notificationId","in":"path","description":"Notification ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Notification update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["Notification"],"summary":"Delete notification","description":"Delete notification","parameters":[{"name":"notificationId","in":"path","description":"Notification ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/register":{"get":{"tags":["Register"],"summary":"Register resource","description":"Register resource","responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/resourceMigrations":{"get":{"tags":["ResourceMigration"],"summary":"List resource migrations","description":"List resource migrations","parameters":[{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["ResourceMigration"],"summary":"Create resource migration","description":"Create resource migration","requestBody":{"description":"Resource Migration Create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/resourceMigrations/{resourceMigrationId}":{"get":{"tags":["ResourceMigration"],"summary":"Get resource migration","description":"Get resource migration","parameters":[{"name":"resourceMigrationId","in":"path","description":"Resource Migration ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["ResourceMigration"],"summary":"Update resource migration","description":"Update resource migration","parameters":[{"name":"resourceMigrationId","in":"path","description":"Resource Migration ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Resource Migration Update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["ResourceMigration"],"summary":"Delete resource migration","description":"Delete resource migration","parameters":[{"name":"resourceMigrationId","in":"path","description":"Resource Migration ID","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/snapshots":{"get":{"tags":["Snapshot"],"summary":"List snapshots","description":"List snapshots","parameters":[{"name":"vmId","in":"path","description":"Filter by VM ID","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"423":{"description":"Locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Snapshot"],"summary":"Create snapshot","description":"Create snapshot","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/storageManagers":{"get":{"tags":["StorageManager"],"summary":"Get storage manager list","description":"Get storage manager list","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.SmRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/storageManagers/{storageManagerId}":{"get":{"tags":["StorageManager"],"summary":"Delete storage manager","description":"Delete storage manager","parameters":[{"name":"storageManagerId","in":"path","description":"Storage manager ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/systemCapacities":{"get":{"tags":["System"],"summary":"List system capacities","description":"List system capacities","parameters":[{"name":"n","in":"query","description":"n","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/systemStats":{"get":{"tags":["System"],"summary":"List system stats","description":"List system stats","parameters":[{"name":"n","in":"query","description":"n","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/systemStatus":{"get":{"tags":["System"],"summary":"List system stats","description":"List system stats","parameters":[{"name":"n","in":"query","description":"n","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/teams":{"get":{"tags":["Team"],"summary":"List teams","description":"List teams","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.TeamRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Team"],"summary":"Create team","description":"Create team","requestBody":{"description":"Team","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/teams/{teamId}":{"get":{"tags":["Team"],"summary":"Get team","description":"Get team","parameters":[{"name":"teamId","in":"path","description":"Team ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["Team"],"summary":"Update team","description":"Update team","parameters":[{"name":"teamId","in":"path","description":"Team ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Team","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["Team"],"summary":"Delete team","description":"Delete team","parameters":[{"name":"teamId","in":"path","description":"Team ID","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content","content":{}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/users":{"get":{"tags":["User"],"summary":"List users","description":"List users","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"discover","in":"query","description":"Discovery mode","schema":{"type":"boolean"}},{"name":"search","in":"query","description":"Search query","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.UserRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/users/{userId}":{"get":{"tags":["User"],"summary":"Get user","description":"Get user","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string"}},{"name":"discover","in":"query","description":"Discovery mode","schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["User"],"summary":"Update user","description":"Update user","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"User update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/users/{userId}/apiKeys":{"post":{"tags":["User"],"summary":"Create API key","description":"Create API key","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"API key create body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/vmActions":{"post":{"tags":["VmAction"],"summary":"Creates a new action","description":"Creates a new action","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"actions body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/vms":{"get":{"tags":["VM"],"summary":"List VMs","description":"List VMs","parameters":[{"name":"all","in":"query","description":"List all","schema":{"type":"boolean"}},{"name":"userId","in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number","schema":{"type":"integer"}},{"name":"pageSize","in":"query","description":"Number of items per page","schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.VmRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["VM"],"summary":"Create VM","description":"Create VM","requestBody":{"description":"VM body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"}},"/v2/vms/{vmId}":{"get":{"tags":["VM"],"summary":"Get VM","description":"Get VM","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"post":{"tags":["VM"],"summary":"Update VM","description":"Update VM","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"VM update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"x-codegen-request-body-name":"body"},"delete":{"tags":["VM"],"summary":"Delete VM","description":"Delete VM","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"post":{"tags":["Snapshot"],"summary":"Get snapshot","description":"Get snapshot","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}},{"name":"snapshotId","in":"path","description":"Snapshot ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]},"delete":{"tags":["Snapshot"],"summary":"Delete snapshot","description":"Delete snapshot","parameters":[{"name":"vmId","in":"path","description":"VM ID","required":true,"schema":{"type":"string"}},{"name":"snapshotId","in":"path","description":"Snapshot ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}},"/v2/workerStatus":{"get":{"tags":["Status"],"summary":"List worker status","description":"List of worker status","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.WorkerStatusRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}}}},"/v2/zones":{"get":{"tags":["Zone"],"summary":"List zones","description":"List zones","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/body.ZoneRead"}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}]}}},"components":{"schemas":{"body.ApiKey":{"type":"object","properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}}},"body.ApiKeyCreate":{"required":["expiresAt","name"],"type":"object","properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}}},"body.ApiKeyCreated":{"type":"object","properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}}},"body.BindingError":{"type":"object","properties":{"validationErrors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"body.CiConfig":{"type":"object","properties":{"config":{"type":"string"}}},"body.ClusterCapacities":{"type":"object","properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}}},"body.ClusterStats":{"type":"object","properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}}},"body.CpuCoreCapacities":{"type":"object","properties":{"total":{"type":"integer"}}},"body.CpuStatus":{"type":"object","properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}}},"body.CpuStatusLoad":{"type":"object","properties":{"cores":{"type":"array","items":{"type":"integer"}},"main":{"type":"number"},"max":{"type":"number"}}},"body.CpuStatusTemp":{"type":"object","properties":{"cores":{"type":"array","items":{"type":"integer"}},"main":{"type":"number"},"max":{"type":"number"}}},"body.CustomDomainRead":{"type":"object","properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}}},"body.DeploymentCommand":{"required":["command"],"type":"object","properties":{"command":{"type":"string","enum":["restart"]}}},"body.DeploymentCreate":{"required":["name"],"type":"object","properties":{"args":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"cpuCores":{"minimum":0.1,"type":"number"},"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"envs":{"maxItems":1000,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Env"}},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"type":"boolean","description":"Deprecated: Use Visibility instead."},"ram":{"minimum":0.1,"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"type":"string","enum":["public","private","auth"]},"volumes":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Volume"}},"zone":{"type":"string","description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone."}}},"body.DeploymentCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.DeploymentRead":{"type":"object","properties":{"accessedAt":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"type":"array","items":{"$ref":"#/components/schemas/body.Env"}},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"type":"array","items":{"type":"string"}},"integrations":{"type":"array","description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"}},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"type":"boolean","description":"Deprecated: Use Visibility instead."},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"type":"array","items":{"type":"string"}},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"type":"array","items":{"$ref":"#/components/schemas/body.Volume"}},"zone":{"type":"string"}}},"body.DeploymentSpecs":{"type":"object","properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}}},"body.DeploymentUpdate":{"required":["name"],"type":"object","properties":{"args":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"cpuCores":{"minimum":0.1,"type":"number"},"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"envs":{"maxItems":1000,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Env"}},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"type":"boolean","description":"Deprecated: Use Visibility instead."},"ram":{"minimum":0.1,"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"type":"string","enum":["public","private","auth"]},"volumes":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.Volume"}}}},"body.DeploymentUpdated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.DiscoverRead":{"type":"object","properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/body.Role"}},"version":{"type":"string"}}},"body.Env":{"required":["name","value"],"type":"object","properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}}},"body.GpuCapacities":{"type":"object","properties":{"total":{"type":"integer"}}},"body.GpuGroupRead":{"type":"object","properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}}},"body.GpuLeaseCreate":{"required":["gpuGroupId"],"type":"object","properties":{"gpuGroupId":{"type":"string","description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease."},"leaseForever":{"type":"boolean","description":"LeaseForever is used to specify whether the lease should be created forever."}}},"body.GpuLeaseCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.GpuLeaseDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.GpuLeaseRead":{"type":"object","properties":{"activatedAt":{"type":"string","description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU."},"active":{"type":"boolean"},"assignedAt":{"type":"string","description":"AssignedAt specifies the time when the lease was assigned to the user."},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"type":"string","description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active."},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"type":"string","description":"VmID is set when the lease is attached to a VM."}}},"body.GpuLeaseUpdate":{"type":"object","properties":{"vmId":{"type":"string","description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned."}}},"body.GpuLeaseUpdated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.GpuStatus":{"type":"object","properties":{"temp":{"type":"array","items":{"$ref":"#/components/schemas/body.GpuStatusTemp"}}}},"body.GpuStatusTemp":{"type":"object","properties":{"main":{"type":"number"}}},"body.HarborWebhook":{"type":"object","properties":{"event_data":{"type":"object","properties":{"repository":{"type":"object","properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}}},"resources":{"type":"array","items":{"type":"object","properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}}}}}},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}}},"body.HostCapacities":{"type":"object","properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"type":"string","description":"Zone is the name of the zone where the host is located."}}},"body.HostRead":{"type":"object","properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"type":"string","description":"Zone is the name of the zone where the host is located."}}},"body.HostStatus":{"type":"object","properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"type":"string","description":"Zone is the name of the zone where the host is located."}}},"body.HttpProxyCreate":{"required":["name"],"type":"object","properties":{"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"name":{"maxLength":30,"minLength":3,"type":"string"}}},"body.HttpProxyRead":{"type":"object","properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}}},"body.HttpProxyUpdate":{"required":["name"],"type":"object","properties":{"customDomain":{"type":"string","description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain."},"name":{"maxLength":30,"minLength":3,"type":"string"}}},"body.JobRead":{"type":"object","properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}}},"body.JobUpdate":{"type":"object","properties":{"status":{"type":"string","enum":["pending","running","failed","terminated","finished","completed"]}}},"body.K8sStats":{"type":"object","properties":{"clusters":{"type":"array","items":{"$ref":"#/components/schemas/body.ClusterStats"}},"podCount":{"type":"integer"}}},"body.NotificationRead":{"type":"object","properties":{"completedAt":{"type":"string"},"content":{"type":"object","additionalProperties":true},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}}},"body.NotificationUpdate":{"type":"object","properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}}},"body.PortCreate":{"required":["name","port","protocol"],"type":"object","properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"type":"string","enum":["tcp","udp"]}}},"body.PortRead":{"type":"object","properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}}},"body.PortUpdate":{"required":["name","port","protocol"],"type":"object","properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"type":"string","enum":["tcp","udp"]}}},"body.PublicKey":{"required":["key","name"],"type":"object","properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}}},"body.Quota":{"type":"object","properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"type":"number","description":"in hours"},"ram":{"type":"number"},"snapshots":{"type":"integer"}}},"body.RamCapacities":{"type":"object","properties":{"total":{"type":"integer"}}},"body.RamStatus":{"type":"object","properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}}},"body.RamStatusLoad":{"type":"object","properties":{"main":{"type":"number"}}},"body.ReplicaStatus":{"type":"object","properties":{"availableReplicas":{"type":"integer","description":"AvailableReplicas is the number of replicas that are available."},"desiredReplicas":{"type":"integer","description":"DesiredReplicas is the number of replicas that the deployment should have."},"readyReplicas":{"type":"integer","description":"ReadyReplicas is the number of replicas that are ready."},"unavailableReplicas":{"type":"integer","description":"UnavailableReplicas is the number of replicas that are unavailable."}}},"body.ResourceMigrationCreate":{"required":["resourceId","type"],"type":"object","properties":{"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"status":{"type":"string","description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending"},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"]},"updateOwner":{"required":["ownerId"],"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner."}}},"body.ResourceMigrationCreated":{"type":"object","properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"type":"string","description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'."},"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"resourceType":{"type":"string","description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment"},"status":{"type":"string","description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted."},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner"},"updateOwner":{"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner."},"userId":{"type":"string","description":"UserID is the ID of the user who initiated the migration."}}},"body.ResourceMigrationRead":{"type":"object","properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"resourceType":{"type":"string","description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment"},"status":{"type":"string","description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted."},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner"},"updateOwner":{"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner."},"userId":{"type":"string","description":"UserID is the ID of the user who initiated the migration."}}},"body.ResourceMigrationUpdate":{"required":["status"],"type":"object","properties":{"code":{"type":"string","description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API"},"status":{"type":"string","description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending"}}},"body.ResourceMigrationUpdated":{"type":"object","properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"type":"string","description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'."},"resourceId":{"type":"string","description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration."},"resourceType":{"type":"string","description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment"},"status":{"type":"string","description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted."},"type":{"type":"string","description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner"},"updateOwner":{"type":"object","properties":{"ownerId":{"type":"string"}},"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner."},"userId":{"type":"string","description":"UserID is the ID of the user who initiated the migration."}}},"body.Role":{"type":"object","properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}},"quota":{"$ref":"#/components/schemas/body.Quota"}}},"body.SmDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.SmRead":{"type":"object","properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}}},"body.SystemCapacities":{"type":"object","properties":{"clusters":{"type":"array","description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"}},"cpuCore":{"type":"object","description":"Total","allOf":[{"$ref":"#/components/schemas/body.CpuCoreCapacities"}]},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"type":"array","description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"}},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}}},"body.SystemStats":{"type":"object","properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}}},"body.SystemStatus":{"type":"object","properties":{"hosts":{"type":"array","items":{"$ref":"#/components/schemas/body.HostStatus"}}}},"body.TeamCreate":{"required":["name"],"type":"object","properties":{"description":{"maxLength":1000,"type":"string"},"members":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.TeamMemberCreate"}},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}}}},"body.TeamMember":{"type":"object","properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}}},"body.TeamMemberCreate":{"required":["id"],"type":"object","properties":{"id":{"type":"string"},"teamRole":{"type":"string","description":"default to MemberRoleAdmin right now"}}},"body.TeamMemberUpdate":{"required":["id"],"type":"object","properties":{"id":{"type":"string"},"teamRole":{"type":"string","description":"default to MemberRoleAdmin right now"}}},"body.TeamRead":{"type":"object","properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"type":"array","items":{"$ref":"#/components/schemas/body.TeamMember"}},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"type":"array","items":{"$ref":"#/components/schemas/body.TeamResource"}},"updatedAt":{"type":"string"}}},"body.TeamResource":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}}},"body.TeamUpdate":{"type":"object","properties":{"description":{"maxLength":1000,"type":"string"},"members":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"}},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}}}},"body.TimestampedSystemCapacities":{"type":"object","properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}}},"body.TimestampedSystemStats":{"type":"object","properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}}},"body.TimestampedSystemStatus":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}}},"body.Usage":{"type":"object","properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}}},"body.UserData":{"required":["key","value"],"type":"object","properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}}},"body.UserRead":{"type":"object","properties":{"admin":{"type":"boolean"},"apiKeys":{"type":"array","items":{"$ref":"#/components/schemas/body.ApiKey"}},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"type":"array","items":{"$ref":"#/components/schemas/body.PublicKey"}},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"type":"array","items":{"$ref":"#/components/schemas/body.UserData"}},"username":{"type":"string"}}},"body.UserUpdate":{"type":"object","properties":{"apiKeys":{"maxItems":100,"minItems":0,"type":"array","description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"}},"publicKeys":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.PublicKey"}},"userData":{"maxItems":100,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.UserData"}}}},"body.VmActionCreate":{"required":["action"],"type":"object","properties":{"action":{"type":"string","enum":["start","stop","restart","repair"]}}},"body.VmActionCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmCreate":{"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object","properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"maxItems":10,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.PortCreate"}},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}}},"body.VmCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmGpuLease":{"type":"object","properties":{"activatedAt":{"type":"string","description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU."},"assignedAt":{"type":"string","description":"AssignedAt specifies the time when the lease was assigned to the user."},"createdAt":{"type":"string"},"expiredAt":{"type":"string","description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired."},"expiresAt":{"type":"string","description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active."},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}}},"body.VmRead":{"type":"object","properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/body.PortRead"}},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string"},"zone":{"type":"string"}}},"body.VmSnapshotCreated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmSnapshotDeleted":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.VmSnapshotRead":{"type":"object","properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}}},"body.VmSpecs":{"type":"object","properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}}},"body.VmUpdate":{"type":"object","properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"maxItems":10,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/body.PortUpdate"}},"ram":{"minimum":1,"type":"integer"}}},"body.VmUpdated":{"type":"object","properties":{"id":{"type":"string"},"jobId":{"type":"string"}}},"body.Volume":{"required":["appPath","name","serverPath"],"type":"object","properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}}},"body.WorkerStatusRead":{"type":"object","properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}}},"body.ZoneEndpoints":{"type":"object","properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}}},"body.ZoneRead":{"type":"object","properties":{"capabilities":{"type":"array","items":{"type":"string"}},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}}},"sys.Error":{"type":"object","properties":{"code":{"type":"string"},"msg":{"type":"string"}}},"sys.ErrorResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/sys.Error"}}}}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"X-Api-Key","in":"header"},"KeycloakOAuth":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token","scopes":{"email":"email","openid":"openid","profile":"profile"}}}}}},"x-original-swagger-version":"2.0"} +{ + "components": { + "schemas": { + "body.ApiKey": { + "properties": { + "createdAt": { "type": "string" }, + "expiresAt": { "type": "string" }, + "name": { "type": "string" } + }, + "type": "object" + }, + "body.ApiKeyCreate": { + "properties": { + "expiresAt": { "type": "string" }, + "name": { "type": "string" } + }, + "required": ["expiresAt", "name"], + "type": "object" + }, + "body.ApiKeyCreated": { + "properties": { + "createdAt": { "type": "string" }, + "expiresAt": { "type": "string" }, + "key": { "type": "string" }, + "name": { "type": "string" } + }, + "type": "object" + }, + "body.BindingError": { + "properties": { + "validationErrors": { + "additionalProperties": { + "items": { "type": "string" }, + "type": "array" + }, + "type": "object" + } + }, + "type": "object" + }, + "body.CiConfig": { + "properties": { "config": { "type": "string" } }, + "type": "object" + }, + "body.ClusterCapacities": { + "properties": { + "cluster": { "type": "string" }, + "cpuCore": { "$ref": "#/components/schemas/body.CpuCoreCapacities" }, + "gpu": { "$ref": "#/components/schemas/body.GpuCapacities" }, + "ram": { "$ref": "#/components/schemas/body.RamCapacities" } + }, + "type": "object" + }, + "body.ClusterStats": { + "properties": { + "cluster": { "type": "string" }, + "podCount": { "type": "integer" } + }, + "type": "object" + }, + "body.CpuCoreCapacities": { + "description": "Total", + "properties": { "total": { "type": "integer" } }, + "type": "object" + }, + "body.CpuStatus": { + "properties": { + "load": { "$ref": "#/components/schemas/body.CpuStatusLoad" }, + "temp": { "$ref": "#/components/schemas/body.CpuStatusTemp" } + }, + "type": "object" + }, + "body.CpuStatusLoad": { + "properties": { + "cores": { + "items": { "type": "integer" }, + "type": "array", + "uniqueItems": false + }, + "main": { "type": "number" }, + "max": { "type": "number" } + }, + "type": "object" + }, + "body.CpuStatusTemp": { + "properties": { + "cores": { + "items": { "type": "integer" }, + "type": "array", + "uniqueItems": false + }, + "main": { "type": "number" }, + "max": { "type": "number" } + }, + "type": "object" + }, + "body.CustomDomainRead": { + "properties": { + "domain": { "type": "string" }, + "secret": { "type": "string" }, + "status": { "type": "string" }, + "url": { "type": "string" } + }, + "type": "object" + }, + "body.DeploymentCommand": { + "properties": { "command": { "enum": ["restart"], "type": "string" } }, + "required": ["command"], + "type": "object" + }, + "body.DeploymentCreate": { + "properties": { + "args": { + "items": { "type": "string" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "cpuCores": { "type": "number" }, + "customDomain": { + "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", + "type": "string" + }, + "envs": { + "items": { "$ref": "#/components/schemas/body.Env" }, + "maxItems": 1000, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "healthCheckPath": { + "maxLength": 1000, + "minLength": 0, + "type": "string" + }, + "image": { "maxLength": 1000, "minLength": 1, "type": "string" }, + "initCommands": { + "items": { "type": "string" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "name": { "maxLength": 30, "minLength": 3, "type": "string" }, + "private": { + "description": "Deprecated: Use Visibility instead.", + "type": "boolean" + }, + "ram": { "type": "number" }, + "replicas": { "maximum": 100, "minimum": 0, "type": "integer" }, + "visibility": { + "enum": ["public", "private", "auth"], + "type": "string" + }, + "volumes": { + "items": { "$ref": "#/components/schemas/body.Volume" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "zone": { + "description": "Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.", + "type": "string" + } + }, + "required": ["name"], + "type": "object" + }, + "body.DeploymentCreated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.DeploymentRead": { + "properties": { + "accessedAt": { "type": "string" }, + "args": { + "items": { "type": "string" }, + "type": "array", + "uniqueItems": false + }, + "createdAt": { "type": "string" }, + "customDomain": { + "$ref": "#/components/schemas/body.CustomDomainRead" + }, + "envs": { + "items": { "$ref": "#/components/schemas/body.Env" }, + "type": "array", + "uniqueItems": false + }, + "error": { "type": "string" }, + "healthCheckPath": { "type": "string" }, + "id": { "type": "string" }, + "image": { "type": "string" }, + "initCommands": { + "items": { "type": "string" }, + "type": "array", + "uniqueItems": false + }, + "integrations": { + "description": "Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub", + "items": { "type": "string" }, + "type": "array", + "uniqueItems": false + }, + "internalPort": { "type": "integer" }, + "name": { "type": "string" }, + "ownerId": { "type": "string" }, + "pingResult": { "type": "integer" }, + "private": { + "description": "Deprecated: Use Visibility instead.", + "type": "boolean" + }, + "repairedAt": { "type": "string" }, + "replicaStatus": { + "$ref": "#/components/schemas/body.ReplicaStatus" + }, + "restartedAt": { "type": "string" }, + "specs": { "$ref": "#/components/schemas/body.DeploymentSpecs" }, + "status": { "type": "string" }, + "storageUrl": { "type": "string" }, + "teams": { + "items": { "type": "string" }, + "type": "array", + "uniqueItems": false + }, + "type": { "type": "string" }, + "updatedAt": { "type": "string" }, + "url": { "type": "string" }, + "visibility": { "type": "string" }, + "volumes": { + "items": { "$ref": "#/components/schemas/body.Volume" }, + "type": "array", + "uniqueItems": false + }, + "zone": { "type": "string" } + }, + "type": "object" + }, + "body.DeploymentSpecs": { + "properties": { + "cpuCores": { "type": "number" }, + "ram": { "type": "number" }, + "replicas": { "type": "integer" } + }, + "type": "object" + }, + "body.DeploymentUpdate": { + "properties": { + "args": { + "items": { "type": "string" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "cpuCores": { "type": "number" }, + "customDomain": { + "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", + "type": "string" + }, + "envs": { + "items": { "$ref": "#/components/schemas/body.Env" }, + "maxItems": 1000, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "healthCheckPath": { + "maxLength": 1000, + "minLength": 0, + "type": "string" + }, + "image": { "maxLength": 1000, "minLength": 1, "type": "string" }, + "initCommands": { + "items": { "type": "string" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "name": { "maxLength": 30, "minLength": 3, "type": "string" }, + "private": { + "description": "Deprecated: Use Visibility instead.", + "type": "boolean" + }, + "ram": { "type": "number" }, + "replicas": { "maximum": 100, "minimum": 0, "type": "integer" }, + "visibility": { + "enum": ["public", "private", "auth"], + "type": "string" + }, + "volumes": { + "items": { "$ref": "#/components/schemas/body.Volume" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + } + }, + "required": ["name"], + "type": "object" + }, + "body.DeploymentUpdated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.DiscoverRead": { + "properties": { + "roles": { + "items": { "$ref": "#/components/schemas/body.Role" }, + "type": "array", + "uniqueItems": false + }, + "version": { "type": "string" } + }, + "type": "object" + }, + "body.Env": { + "properties": { + "name": { "maxLength": 100, "minLength": 1, "type": "string" }, + "value": { "maxLength": 10000, "minLength": 1, "type": "string" } + }, + "required": ["name", "value"], + "type": "object" + }, + "body.GpuCapacities": { + "properties": { "total": { "type": "integer" } }, + "type": "object" + }, + "body.GpuGroupRead": { + "properties": { + "available": { "type": "integer" }, + "displayName": { "type": "string" }, + "id": { "type": "string" }, + "name": { "type": "string" }, + "total": { "type": "integer" }, + "vendor": { "type": "string" }, + "zone": { "type": "string" } + }, + "type": "object" + }, + "body.GpuLeaseCreate": { + "properties": { + "gpuGroupId": { + "description": "GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.", + "type": "string" + }, + "leaseForever": { + "description": "LeaseForever is used to specify whether the lease should be created forever.", + "type": "boolean" + } + }, + "required": ["gpuGroupId"], + "type": "object" + }, + "body.GpuLeaseCreated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.GpuLeaseDeleted": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.GpuLeaseRead": { + "properties": { + "activatedAt": { + "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", + "type": "string" + }, + "active": { "type": "boolean" }, + "assignedAt": { + "description": "AssignedAt specifies the time when the lease was assigned to the user.", + "type": "string" + }, + "createdAt": { "type": "string" }, + "expiredAt": { "type": "string" }, + "expiresAt": { + "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", + "type": "string" + }, + "gpuGroupId": { "type": "string" }, + "id": { "type": "string" }, + "leaseDuration": { "type": "number" }, + "queuePosition": { "type": "integer" }, + "userId": { "type": "string" }, + "vmId": { + "description": "VmID is set when the lease is attached to a VM.", + "type": "string" + } + }, + "type": "object" + }, + "body.GpuLeaseUpdate": { + "properties": { + "vmId": { + "description": "VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.", + "type": "string" + } + }, + "type": "object" + }, + "body.GpuLeaseUpdated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.GpuStatus": { + "properties": { + "temp": { + "items": { "$ref": "#/components/schemas/body.GpuStatusTemp" }, + "type": "array", + "uniqueItems": false + } + }, + "type": "object" + }, + "body.GpuStatusTemp": { + "properties": { "main": { "type": "number" } }, + "type": "object" + }, + "body.HarborWebhook": { + "properties": { + "event_data": { + "properties": { + "repository": { + "properties": { + "date_created": { "type": "integer" }, + "name": { "type": "string" }, + "namespace": { "type": "string" }, + "repo_full_name": { "type": "string" }, + "repo_type": { "type": "string" } + }, + "type": "object" + }, + "resources": { + "items": { + "properties": { + "digest": { "type": "string" }, + "resource_url": { "type": "string" }, + "tag": { "type": "string" } + }, + "type": "object" + }, + "type": "array", + "uniqueItems": false + } + }, + "type": "object" + }, + "occur_at": { "type": "integer" }, + "operator": { "type": "string" }, + "type": { "type": "string" } + }, + "type": "object" + }, + "body.HostCapacities": { + "properties": { + "cpuCore": { "$ref": "#/components/schemas/body.CpuCoreCapacities" }, + "displayName": { "type": "string" }, + "gpu": { "$ref": "#/components/schemas/body.GpuCapacities" }, + "name": { "type": "string" }, + "ram": { "$ref": "#/components/schemas/body.RamCapacities" }, + "zone": { + "description": "Zone is the name of the zone where the host is located.", + "type": "string" + } + }, + "type": "object" + }, + "body.HostRead": { + "properties": { + "displayName": { "type": "string" }, + "name": { "type": "string" }, + "zone": { + "description": "Zone is the name of the zone where the host is located.", + "type": "string" + } + }, + "type": "object" + }, + "body.HostStatus": { + "properties": { + "cpu": { "$ref": "#/components/schemas/body.CpuStatus" }, + "displayName": { "type": "string" }, + "gpu": { "$ref": "#/components/schemas/body.GpuStatus" }, + "name": { "type": "string" }, + "ram": { "$ref": "#/components/schemas/body.RamStatus" }, + "zone": { + "description": "Zone is the name of the zone where the host is located.", + "type": "string" + } + }, + "type": "object" + }, + "body.HttpProxyCreate": { + "properties": { + "customDomain": { + "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", + "type": "string" + }, + "name": { "maxLength": 30, "minLength": 3, "type": "string" } + }, + "required": ["name"], + "type": "object" + }, + "body.HttpProxyRead": { + "properties": { + "customDomain": { + "$ref": "#/components/schemas/body.CustomDomainRead" + }, + "name": { "type": "string" }, + "url": { "type": "string" } + }, + "type": "object" + }, + "body.HttpProxyUpdate": { + "properties": { + "customDomain": { + "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", + "type": "string" + }, + "name": { "maxLength": 30, "minLength": 3, "type": "string" } + }, + "required": ["name"], + "type": "object" + }, + "body.JobRead": { + "properties": { + "createdAt": { "type": "string" }, + "finishedAt": { "type": "string" }, + "id": { "type": "string" }, + "lastError": { "type": "string" }, + "lastRunAt": { "type": "string" }, + "runAfter": { "type": "string" }, + "status": { "type": "string" }, + "type": { "type": "string" }, + "userId": { "type": "string" } + }, + "type": "object" + }, + "body.JobUpdate": { + "properties": { + "status": { + "enum": [ + "pending", + "running", + "failed", + "terminated", + "finished", + "completed" + ], + "type": "string" + } + }, + "type": "object" + }, + "body.K8sStats": { + "properties": { + "clusters": { + "items": { "$ref": "#/components/schemas/body.ClusterStats" }, + "type": "array", + "uniqueItems": false + }, + "podCount": { "type": "integer" } + }, + "type": "object" + }, + "body.NotificationRead": { + "properties": { + "completedAt": { "type": "string" }, + "content": { "additionalProperties": {}, "type": "object" }, + "createdAt": { "type": "string" }, + "id": { "type": "string" }, + "readAt": { "type": "string" }, + "toastedAt": { "type": "string" }, + "type": { "type": "string" }, + "userId": { "type": "string" } + }, + "type": "object" + }, + "body.NotificationUpdate": { + "properties": { + "read": { "type": "boolean" }, + "toasted": { "type": "boolean" } + }, + "type": "object" + }, + "body.PortCreate": { + "properties": { + "httpProxy": { "$ref": "#/components/schemas/body.HttpProxyCreate" }, + "name": { "maxLength": 100, "minLength": 1, "type": "string" }, + "port": { "maximum": 65535, "minimum": 1, "type": "integer" }, + "protocol": { "enum": ["tcp", "udp"], "type": "string" } + }, + "required": ["name", "port", "protocol"], + "type": "object" + }, + "body.PortRead": { + "properties": { + "externalPort": { "type": "integer" }, + "httpProxy": { "$ref": "#/components/schemas/body.HttpProxyRead" }, + "name": { "type": "string" }, + "port": { "type": "integer" }, + "protocol": { "type": "string" } + }, + "type": "object" + }, + "body.PortUpdate": { + "properties": { + "httpProxy": { "$ref": "#/components/schemas/body.HttpProxyUpdate" }, + "name": { "maxLength": 100, "minLength": 1, "type": "string" }, + "port": { "maximum": 65535, "minimum": 1, "type": "integer" }, + "protocol": { "enum": ["tcp", "udp"], "type": "string" } + }, + "required": ["name", "port", "protocol"], + "type": "object" + }, + "body.PublicKey": { + "properties": { + "key": { "type": "string" }, + "name": { "maxLength": 30, "minLength": 1, "type": "string" } + }, + "required": ["key", "name"], + "type": "object" + }, + "body.Quota": { + "properties": { + "cpuCores": { "type": "number" }, + "diskSize": { "type": "number" }, + "gpuLeaseDuration": { "description": "in hours", "type": "number" }, + "ram": { "type": "number" }, + "snapshots": { "type": "integer" } + }, + "type": "object" + }, + "body.RamCapacities": { + "properties": { "total": { "type": "integer" } }, + "type": "object" + }, + "body.RamStatus": { + "properties": { + "load": { "$ref": "#/components/schemas/body.RamStatusLoad" } + }, + "type": "object" + }, + "body.RamStatusLoad": { + "properties": { "main": { "type": "number" } }, + "type": "object" + }, + "body.ReplicaStatus": { + "properties": { + "availableReplicas": { + "description": "AvailableReplicas is the number of replicas that are available.", + "type": "integer" + }, + "desiredReplicas": { + "description": "DesiredReplicas is the number of replicas that the deployment should have.", + "type": "integer" + }, + "readyReplicas": { + "description": "ReadyReplicas is the number of replicas that are ready.", + "type": "integer" + }, + "unavailableReplicas": { + "description": "UnavailableReplicas is the number of replicas that are unavailable.", + "type": "integer" + } + }, + "type": "object" + }, + "body.ResourceMigrationCreate": { + "properties": { + "resourceId": { + "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", + "type": "string" + }, + "status": { + "description": "Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending", + "type": "string" + }, + "type": { + "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", + "enum": ["updateOwner"], + "type": "string" + }, + "updateOwner": { + "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.", + "properties": { "ownerId": { "type": "string" } }, + "required": ["ownerId"], + "type": "object" + } + }, + "required": ["resourceId", "type"], + "type": "object" + }, + "body.ResourceMigrationCreated": { + "properties": { + "createdAt": { "type": "string" }, + "deletedAt": { "type": "string" }, + "id": { "type": "string" }, + "jobId": { + "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.", + "type": "string" + }, + "resourceId": { + "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", + "type": "string" + }, + "resourceType": { + "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", + "type": "string" + }, + "status": { + "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", + "type": "string" + }, + "type": { + "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", + "type": "string" + }, + "updateOwner": { + "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", + "properties": { "ownerId": { "type": "string" } }, + "type": "object" + }, + "userId": { + "description": "UserID is the ID of the user who initiated the migration.", + "type": "string" + } + }, + "type": "object" + }, + "body.ResourceMigrationRead": { + "properties": { + "createdAt": { "type": "string" }, + "deletedAt": { "type": "string" }, + "id": { "type": "string" }, + "resourceId": { + "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", + "type": "string" + }, + "resourceType": { + "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", + "type": "string" + }, + "status": { + "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", + "type": "string" + }, + "type": { + "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", + "type": "string" + }, + "updateOwner": { + "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", + "properties": { "ownerId": { "type": "string" } }, + "type": "object" + }, + "userId": { + "description": "UserID is the ID of the user who initiated the migration.", + "type": "string" + } + }, + "type": "object" + }, + "body.ResourceMigrationUpdate": { + "properties": { + "code": { + "description": "Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API", + "type": "string" + }, + "status": { + "description": "Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending", + "type": "string" + } + }, + "required": ["status"], + "type": "object" + }, + "body.ResourceMigrationUpdated": { + "properties": { + "createdAt": { "type": "string" }, + "deletedAt": { "type": "string" }, + "id": { "type": "string" }, + "jobId": { + "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.", + "type": "string" + }, + "resourceId": { + "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", + "type": "string" + }, + "resourceType": { + "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", + "type": "string" + }, + "status": { + "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", + "type": "string" + }, + "type": { + "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", + "type": "string" + }, + "updateOwner": { + "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", + "properties": { "ownerId": { "type": "string" } }, + "type": "object" + }, + "userId": { + "description": "UserID is the ID of the user who initiated the migration.", + "type": "string" + } + }, + "type": "object" + }, + "body.Role": { + "properties": { + "description": { "type": "string" }, + "name": { "type": "string" }, + "permissions": { + "items": { "type": "string" }, + "type": "array", + "uniqueItems": false + }, + "quota": { "$ref": "#/components/schemas/body.Quota" } + }, + "type": "object" + }, + "body.SmDeleted": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.SmRead": { + "properties": { + "createdAt": { "type": "string" }, + "id": { "type": "string" }, + "ownerId": { "type": "string" }, + "url": { "type": "string" }, + "zone": { "type": "string" } + }, + "type": "object" + }, + "body.SystemCapacities": { + "properties": { + "clusters": { + "description": "Per Cluster", + "items": { "$ref": "#/components/schemas/body.ClusterCapacities" }, + "type": "array", + "uniqueItems": false + }, + "cpuCore": { "$ref": "#/components/schemas/body.CpuCoreCapacities" }, + "gpu": { "$ref": "#/components/schemas/body.GpuCapacities" }, + "hosts": { + "description": "Per Host", + "items": { "$ref": "#/components/schemas/body.HostCapacities" }, + "type": "array", + "uniqueItems": false + }, + "ram": { "$ref": "#/components/schemas/body.RamCapacities" } + }, + "type": "object" + }, + "body.SystemStats": { + "properties": { + "k8s": { "$ref": "#/components/schemas/body.K8sStats" } + }, + "type": "object" + }, + "body.SystemStatus": { + "properties": { + "hosts": { + "items": { "$ref": "#/components/schemas/body.HostStatus" }, + "type": "array", + "uniqueItems": false + } + }, + "type": "object" + }, + "body.TeamCreate": { + "properties": { + "description": { "maxLength": 1000, "type": "string" }, + "members": { + "items": { "$ref": "#/components/schemas/body.TeamMemberCreate" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "name": { "maxLength": 100, "minLength": 1, "type": "string" }, + "resources": { + "items": { "type": "string" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + } + }, + "required": ["name"], + "type": "object" + }, + "body.TeamMember": { + "properties": { + "addedAt": { "type": "string" }, + "email": { "type": "string" }, + "firstName": { "type": "string" }, + "gravatarUrl": { "type": "string" }, + "id": { "type": "string" }, + "joinedAt": { "type": "string" }, + "lastName": { "type": "string" }, + "memberStatus": { "type": "string" }, + "teamRole": { "type": "string" }, + "username": { "type": "string" } + }, + "type": "object" + }, + "body.TeamMemberCreate": { + "properties": { + "id": { "type": "string" }, + "teamRole": { + "description": "default to MemberRoleAdmin right now", + "type": "string" + } + }, + "required": ["id"], + "type": "object" + }, + "body.TeamMemberUpdate": { + "properties": { + "id": { "type": "string" }, + "teamRole": { + "description": "default to MemberRoleAdmin right now", + "type": "string" + } + }, + "required": ["id"], + "type": "object" + }, + "body.TeamRead": { + "properties": { + "createdAt": { "type": "string" }, + "description": { "type": "string" }, + "id": { "type": "string" }, + "members": { + "items": { "$ref": "#/components/schemas/body.TeamMember" }, + "type": "array", + "uniqueItems": false + }, + "name": { "type": "string" }, + "ownerId": { "type": "string" }, + "resources": { + "items": { "$ref": "#/components/schemas/body.TeamResource" }, + "type": "array", + "uniqueItems": false + }, + "updatedAt": { "type": "string" } + }, + "type": "object" + }, + "body.TeamResource": { + "properties": { + "id": { "type": "string" }, + "name": { "type": "string" }, + "type": { "type": "string" } + }, + "type": "object" + }, + "body.TeamUpdate": { + "properties": { + "description": { "maxLength": 1000, "type": "string" }, + "members": { + "items": { "$ref": "#/components/schemas/body.TeamMemberUpdate" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "name": { "maxLength": 100, "minLength": 1, "type": "string" }, + "resources": { + "items": { "type": "string" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + } + }, + "type": "object" + }, + "body.TimestampedSystemCapacities": { + "properties": { + "capacities": { + "$ref": "#/components/schemas/body.SystemCapacities" + }, + "timestamp": { "type": "string" } + }, + "type": "object" + }, + "body.TimestampedSystemStats": { + "properties": { + "stats": { "$ref": "#/components/schemas/body.SystemStats" }, + "timestamp": { "type": "string" } + }, + "type": "object" + }, + "body.TimestampedSystemStatus": { + "properties": { + "status": { "$ref": "#/components/schemas/body.SystemStatus" }, + "timestamp": { "type": "string" } + }, + "type": "object" + }, + "body.Usage": { + "properties": { + "cpuCores": { "type": "number" }, + "diskSize": { "type": "integer" }, + "ram": { "type": "number" } + }, + "type": "object" + }, + "body.UserData": { + "properties": { + "key": { "maxLength": 255, "minLength": 1, "type": "string" }, + "value": { "maxLength": 255, "minLength": 1, "type": "string" } + }, + "required": ["key", "value"], + "type": "object" + }, + "body.UserRead": { + "properties": { + "admin": { "type": "boolean" }, + "apiKeys": { + "items": { "$ref": "#/components/schemas/body.ApiKey" }, + "type": "array", + "uniqueItems": false + }, + "email": { "type": "string" }, + "firstName": { "type": "string" }, + "gravatarUrl": { "type": "string" }, + "id": { "type": "string" }, + "lastName": { "type": "string" }, + "publicKeys": { + "items": { "$ref": "#/components/schemas/body.PublicKey" }, + "type": "array", + "uniqueItems": false + }, + "quota": { "$ref": "#/components/schemas/body.Quota" }, + "role": { "$ref": "#/components/schemas/body.Role" }, + "storageUrl": { "type": "string" }, + "usage": { "$ref": "#/components/schemas/body.Usage" }, + "userData": { + "items": { "$ref": "#/components/schemas/body.UserData" }, + "type": "array", + "uniqueItems": false + }, + "username": { "type": "string" } + }, + "type": "object" + }, + "body.UserUpdate": { + "properties": { + "apiKeys": { + "description": "ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.", + "items": { "$ref": "#/components/schemas/body.ApiKey" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "publicKeys": { + "items": { "$ref": "#/components/schemas/body.PublicKey" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "userData": { + "items": { "$ref": "#/components/schemas/body.UserData" }, + "maxItems": 100, + "minItems": 0, + "type": "array", + "uniqueItems": false + } + }, + "type": "object" + }, + "body.VmActionCreate": { + "properties": { + "action": { + "enum": ["start", "stop", "restart", "repair"], + "type": "string" + } + }, + "required": ["action"], + "type": "object" + }, + "body.VmActionCreated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.VmCreate": { + "properties": { + "cpuCores": { "minimum": 1, "type": "integer" }, + "diskSize": { "minimum": 10, "type": "integer" }, + "name": { "maxLength": 30, "minLength": 3, "type": "string" }, + "ports": { + "items": { "$ref": "#/components/schemas/body.PortCreate" }, + "maxItems": 10, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "ram": { "minimum": 1, "type": "integer" }, + "sshPublicKey": { "type": "string" }, + "zone": { "type": "string" } + }, + "required": ["cpuCores", "diskSize", "name", "ram", "sshPublicKey"], + "type": "object" + }, + "body.VmCreated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.VmDeleted": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.VmGpuLease": { + "properties": { + "activatedAt": { + "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", + "type": "string" + }, + "assignedAt": { + "description": "AssignedAt specifies the time when the lease was assigned to the user.", + "type": "string" + }, + "createdAt": { "type": "string" }, + "expiredAt": { + "description": "ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.", + "type": "string" + }, + "expiresAt": { + "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", + "type": "string" + }, + "gpuGroupId": { "type": "string" }, + "id": { "type": "string" }, + "leaseDuration": { "type": "number" } + }, + "type": "object" + }, + "body.VmRead": { + "properties": { + "accessedAt": { "type": "string" }, + "createdAt": { "type": "string" }, + "gpu": { "$ref": "#/components/schemas/body.VmGpuLease" }, + "host": { "type": "string" }, + "id": { "type": "string" }, + "internalName": { "type": "string" }, + "name": { "type": "string" }, + "ownerId": { "type": "string" }, + "ports": { + "items": { "$ref": "#/components/schemas/body.PortRead" }, + "type": "array", + "uniqueItems": false + }, + "repairedAt": { "type": "string" }, + "specs": { "$ref": "#/components/schemas/body.VmSpecs" }, + "sshConnectionString": { "type": "string" }, + "sshPublicKey": { "type": "string" }, + "status": { "type": "string" }, + "teams": { + "items": { "type": "string" }, + "type": "array", + "uniqueItems": false + }, + "updatedAt": { "type": "string" }, + "zone": { "type": "string" } + }, + "type": "object" + }, + "body.VmSnapshotCreated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.VmSnapshotDeleted": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.VmSnapshotRead": { + "properties": { + "created": { "type": "string" }, + "id": { "type": "string" }, + "name": { "type": "string" }, + "status": { "type": "string" } + }, + "type": "object" + }, + "body.VmSpecs": { + "properties": { + "cpuCores": { "type": "integer" }, + "diskSize": { "type": "integer" }, + "ram": { "type": "integer" } + }, + "type": "object" + }, + "body.VmUpdate": { + "properties": { + "cpuCores": { "minimum": 1, "type": "integer" }, + "name": { "maxLength": 30, "minLength": 3, "type": "string" }, + "ports": { + "items": { "$ref": "#/components/schemas/body.PortUpdate" }, + "maxItems": 10, + "minItems": 0, + "type": "array", + "uniqueItems": false + }, + "ram": { "minimum": 1, "type": "integer" } + }, + "type": "object" + }, + "body.VmUpdated": { + "properties": { + "id": { "type": "string" }, + "jobId": { "type": "string" } + }, + "type": "object" + }, + "body.Volume": { + "properties": { + "appPath": { "maxLength": 255, "minLength": 1, "type": "string" }, + "name": { "maxLength": 30, "minLength": 3, "type": "string" }, + "serverPath": { "maxLength": 255, "minLength": 1, "type": "string" } + }, + "required": ["appPath", "name", "serverPath"], + "type": "object" + }, + "body.WorkerStatusRead": { + "properties": { + "name": { "type": "string" }, + "reportedAt": { "type": "string" }, + "status": { "type": "string" } + }, + "type": "object" + }, + "body.ZoneEndpoints": { + "properties": { + "deployment": { "type": "string" }, + "storage": { "type": "string" }, + "vm": { "type": "string" }, + "vmApp": { "type": "string" } + }, + "type": "object" + }, + "body.ZoneRead": { + "properties": { + "capabilities": { + "items": { "type": "string" }, + "type": "array", + "uniqueItems": false + }, + "description": { "type": "string" }, + "enabled": { "type": "boolean" }, + "endpoints": { "$ref": "#/components/schemas/body.ZoneEndpoints" }, + "legacy": { "type": "boolean" }, + "name": { "type": "string" } + }, + "type": "object" + }, + "sys.Error": { + "properties": { + "code": { "type": "string" }, + "msg": { "type": "string" } + }, + "type": "object" + }, + "sys.ErrorResponse": { + "properties": { + "errors": { + "items": { "$ref": "#/components/schemas/sys.Error" }, + "type": "array", + "uniqueItems": false + } + }, + "type": "object" + } + }, + "securitySchemes": { + "ApiKeyAuth": { + "flows": { + "authorizationCode": { + "authorizationUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth", + "tokenUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token" + } + }, + "in": "header", + "type": "oauth2" + } + } + }, + "info": { + "contact": { + "name": "Support", + "url": "https://github.com/kthcloud/go-deploy" + }, + "description": "This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.", + "license": { + "name": "MIT License", + "url": "https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme" + }, + "termsOfService": "http://swagger.io/terms/", + "title": "go-deploy API", + "version": "1.0" + }, + "externalDocs": { "description": "", "url": "" }, + "paths": { + "/v2/deployments": { + "get": { + "description": "List deployments", + "parameters": [ + { + "description": "List all", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Filter by user ID", + "in": "query", + "name": "userId", + "schema": { "type": "string" } + }, + { + "description": "Include shared", + "in": "query", + "name": "shared", + "schema": { "type": "boolean" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.DeploymentRead" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List deployments", + "tags": ["Deployment"] + }, + "post": { + "description": "Create deployment", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.DeploymentCreate" } + } + }, + "description": "Deployment body", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.DeploymentRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Create deployment", + "tags": ["Deployment"] + } + }, + "/v2/deployments/{deploymentId}": { + "delete": { + "description": "Delete deployment", + "parameters": [ + { + "description": "Deployment ID", + "in": "path", + "name": "deploymentId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.DeploymentCreated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete deployment", + "tags": ["Deployment"] + }, + "get": { + "description": "Get deployment", + "parameters": [ + { + "description": "Deployment ID", + "in": "path", + "name": "deploymentId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.DeploymentRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get deployment", + "tags": ["Deployment"] + }, + "post": { + "description": "Update deployment", + "parameters": [ + { + "description": "Deployment ID", + "in": "path", + "name": "deploymentId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.DeploymentUpdate" } + } + }, + "description": "Deployment update", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.DeploymentUpdated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update deployment", + "tags": ["Deployment"] + } + }, + "/v2/deployments/{deploymentId}/ciConfig": { + "get": { + "description": "Get CI config", + "parameters": [ + { + "description": "Deployment ID", + "in": "path", + "name": "deploymentId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.CiConfig" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get CI config", + "tags": ["Deployment"] + } + }, + "/v2/deployments/{deploymentId}/command": { + "post": { + "description": "Do command", + "parameters": [ + { + "description": "Deployment ID", + "in": "path", + "name": "deploymentId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.DeploymentCommand" + } + } + }, + "description": "Command body", + "required": true + }, + "responses": { + "204": { "description": "No Content" }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "423": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Locked" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Do command", + "tags": ["Deployment"] + } + }, + "/v2/deployments/{deploymentId}/logs": { + "get": { + "description": "Get logs using Server-Sent Events", + "parameters": [ + { + "description": "Deployment ID", + "in": "path", + "name": "deploymentId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { "schema": { "type": "string" } } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get logs using Server-Sent Events", + "tags": ["Deployment"] + } + }, + "/v2/discover": { + "get": { + "description": "Discover", + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.DiscoverRead" } + } + }, + "description": "OK" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "Discover", + "tags": ["Discover"] + } + }, + "/v2/gpuGroups": { + "get": { + "description": "List GPU groups", + "parameters": [ + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.GpuGroupRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "423": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Locked" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List GPU groups", + "tags": ["GpuGroup"] + } + }, + "/v2/gpuGroups/{gpuGroupId}": { + "get": { + "description": "Get GPU group", + "parameters": [ + { + "description": "GPU group ID", + "in": "path", + "name": "gpuGroupId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.GpuGroupRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "423": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Locked" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get GPU group", + "tags": ["GpuGroup"] + } + }, + "/v2/gpuLeases": { + "get": { + "description": "List GPU leases", + "parameters": [ + { + "description": "List all", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Filter by VM ID", + "in": "query", + "name": "vmId", + "schema": { "type": "string" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.GpuLeaseRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "423": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Locked" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List GPU leases", + "tags": ["GpuLease"] + }, + "post": { + "description": "Create GPU lease", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.GpuLeaseCreate" } + } + }, + "description": "GPU lease", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.GpuLeaseCreated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Create GPU Lease", + "tags": ["GpuLease"] + } + }, + "/v2/gpuLeases/{gpuLeaseId}": { + "delete": { + "description": "Delete GPU lease", + "parameters": [ + { + "description": "GPU lease ID", + "in": "path", + "name": "gpuLeaseId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.GpuLeaseDeleted" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete GPU lease", + "tags": ["GpuLease"] + }, + "get": { + "description": "Get GPU lease", + "parameters": [ + { + "description": "GPU lease ID", + "in": "path", + "name": "gpuLeaseId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.GpuLeaseRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "423": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Locked" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get GPU lease", + "tags": ["GpuLease"] + }, + "post": { + "description": "Update GPU lease", + "parameters": [ + { + "description": "GPU lease ID", + "in": "path", + "name": "gpuLeaseId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.GpuLeaseUpdate" } + } + }, + "description": "GPU lease", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.GpuLeaseUpdated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update GPU lease", + "tags": ["GpuLease"] + } + }, + "/v2/hooks/harbor": { + "post": { + "description": "Handle Harbor hook", + "parameters": [ + { + "description": "Basic auth token", + "in": "header", + "name": "Authorization", + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.HarborWebhook" } + } + }, + "description": "Harbor webhook body", + "required": true + }, + "responses": { + "204": { "description": "No Content" }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "Handle Harbor hook", + "tags": ["Deployment"] + } + }, + "/v2/hosts": { + "get": { + "description": "List Hosts", + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.HostRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "List Hosts", + "tags": ["Host"] + } + }, + "/v2/jobs": { + "get": { + "description": "List jobs", + "parameters": [ + { + "description": "List all", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Filter by user ID", + "in": "query", + "name": "userId", + "schema": { "type": "string" } + }, + { + "description": "Filter by type", + "in": "query", + "name": "type", + "schema": { "type": "string" } + }, + { + "description": "Filter by status", + "in": "query", + "name": "status", + "schema": { "type": "string" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.JobRead" }, + "type": "array" + } + } + }, + "description": "OK" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List jobs", + "tags": ["Job"] + } + }, + "/v2/jobs/{jobId}": { + "get": { + "description": "GetJob job by id", + "parameters": [ + { + "description": "Job ID", + "in": "path", + "name": "jobId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.JobRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "GetJob job by id", + "tags": ["Job"] + }, + "post": { + "description": "Update job. Only allowed for admins.", + "parameters": [ + { + "description": "Job ID", + "in": "path", + "name": "jobId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.JobUpdate" } + } + }, + "description": "Job update", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.JobRead" } + } + }, + "description": "OK" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update job", + "tags": ["Job"] + } + }, + "/v2/metrics": { + "get": { + "description": "Get metrics", + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { "schema": { "type": "string" } } + }, + "description": "OK" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "Get metrics", + "tags": ["Metrics"] + } + }, + "/v2/notifications": { + "get": { + "description": "List notifications", + "parameters": [ + { + "description": "List all notifications", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Filter by user ID", + "in": "query", + "name": "userId", + "schema": { "type": "string" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.NotificationRead" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List notifications", + "tags": ["Notification"] + } + }, + "/v2/notifications/{notificationId}": { + "delete": { + "description": "Delete notification", + "parameters": [ + { + "description": "Notification ID", + "in": "path", + "name": "notificationId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { "schema": { "type": "object" } } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete notification", + "tags": ["Notification"] + }, + "get": { + "description": "Get notification", + "parameters": [ + { + "description": "Notification ID", + "in": "path", + "name": "notificationId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.NotificationRead" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get notification", + "tags": ["Notification"] + }, + "post": { + "description": "Update notification", + "parameters": [ + { + "description": "Notification ID", + "in": "path", + "name": "notificationId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.NotificationUpdate" + } + } + }, + "description": "Notification update", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { "schema": { "type": "object" } } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update notification", + "tags": ["Notification"] + } + }, + "/v2/register": { + "get": { + "description": "Register resource", + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "204": { "description": "No Content" }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "Register resource", + "tags": ["Register"] + } + }, + "/v2/resourceMigrations": { + "get": { + "description": "List resource migrations", + "parameters": [ + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.ResourceMigrationRead" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List resource migrations", + "tags": ["ResourceMigration"] + }, + "post": { + "description": "Create resource migration", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.ResourceMigrationCreate" + } + } + }, + "description": "Resource Migration Create", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.ResourceMigrationCreated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Create resource migration", + "tags": ["ResourceMigration"] + } + }, + "/v2/resourceMigrations/{resourceMigrationId}": { + "delete": { + "description": "Delete resource migration", + "parameters": [ + { + "description": "Resource Migration ID", + "in": "path", + "name": "resourceMigrationId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "204": { "description": "No Content" }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete resource migration", + "tags": ["ResourceMigration"] + }, + "get": { + "description": "Get resource migration", + "parameters": [ + { + "description": "Resource Migration ID", + "in": "path", + "name": "resourceMigrationId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.ResourceMigrationRead" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get resource migration", + "tags": ["ResourceMigration"] + }, + "post": { + "description": "Update resource migration", + "parameters": [ + { + "description": "Resource Migration ID", + "in": "path", + "name": "resourceMigrationId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.ResourceMigrationUpdate" + } + } + }, + "description": "Resource Migration Update", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.ResourceMigrationUpdated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update resource migration", + "tags": ["ResourceMigration"] + } + }, + "/v2/snapshots": { + "get": { + "description": "List snapshots", + "parameters": [ + { + "description": "Filter by VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.VmSnapshotRead" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "423": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Locked" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List snapshots", + "tags": ["Snapshot"] + }, + "post": { + "description": "Create snapshot", + "parameters": [ + { + "description": "VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.VmSnapshotCreated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Create snapshot", + "tags": ["Snapshot"] + } + }, + "/v2/storageManagers": { + "get": { + "description": "Get storage manager list", + "parameters": [ + { + "description": "List all", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.SmRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get storage manager list", + "tags": ["StorageManager"] + } + }, + "/v2/storageManagers/{storageManagerId}": { + "get": { + "description": "Delete storage manager", + "parameters": [ + { + "description": "Storage manager ID", + "in": "path", + "name": "storageManagerId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.SmDeleted" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete storage manager", + "tags": ["StorageManager"] + } + }, + "/v2/systemCapacities": { + "get": { + "description": "List system capacities", + "parameters": [ + { + "description": "n", + "in": "query", + "name": "n", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.TimestampedSystemCapacities" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "List system capacities", + "tags": ["System"] + } + }, + "/v2/systemStats": { + "get": { + "description": "List system stats", + "parameters": [ + { + "description": "n", + "in": "query", + "name": "n", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.TimestampedSystemStats" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "List system stats", + "tags": ["System"] + } + }, + "/v2/systemStatus": { + "get": { + "description": "List system stats", + "parameters": [ + { + "description": "n", + "in": "query", + "name": "n", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.TimestampedSystemStatus" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "List system stats", + "tags": ["System"] + } + }, + "/v2/teams": { + "get": { + "description": "List teams", + "parameters": [ + { + "description": "List all", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Filter by user ID", + "in": "query", + "name": "userId", + "schema": { "type": "string" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.TeamRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List teams", + "tags": ["Team"] + }, + "post": { + "description": "Create team", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.TeamCreate" } + } + }, + "description": "Team", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.TeamRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Create team", + "tags": ["Team"] + } + }, + "/v2/teams/{teamId}": { + "delete": { + "description": "Delete team", + "parameters": [ + { + "description": "Team ID", + "in": "path", + "name": "teamId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "204": { "description": "No Content" }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete team", + "tags": ["Team"] + }, + "get": { + "description": "Get team", + "parameters": [ + { + "description": "Team ID", + "in": "path", + "name": "teamId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.TeamRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get team", + "tags": ["Team"] + }, + "post": { + "description": "Update team", + "parameters": [ + { + "description": "Team ID", + "in": "path", + "name": "teamId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.TeamUpdate" } + } + }, + "description": "Team", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.TeamRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.BindingError" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update team", + "tags": ["Team"] + } + }, + "/v2/users": { + "get": { + "description": "List users", + "parameters": [ + { + "description": "List all", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Discovery mode", + "in": "query", + "name": "discover", + "schema": { "type": "boolean" } + }, + { + "description": "Search query", + "in": "query", + "name": "search", + "schema": { "type": "string" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.UserRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List users", + "tags": ["User"] + } + }, + "/v2/users/{userId}": { + "get": { + "description": "Get user", + "parameters": [ + { + "description": "User ID", + "in": "path", + "name": "userId", + "required": true, + "schema": { "type": "string" } + }, + { + "description": "Discovery mode", + "in": "query", + "name": "discover", + "schema": { "type": "boolean" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.UserRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get user", + "tags": ["User"] + }, + "post": { + "description": "Update user", + "parameters": [ + { + "description": "User ID", + "in": "path", + "name": "userId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.UserUpdate" } + } + }, + "description": "User update", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.UserRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update user", + "tags": ["User"] + } + }, + "/v2/users/{userId}/apiKeys": { + "post": { + "description": "Create API key", + "parameters": [ + { + "description": "User ID", + "in": "path", + "name": "userId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.ApiKeyCreate" } + } + }, + "description": "API key create body", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.ApiKeyCreated" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Create API key", + "tags": ["User"] + } + }, + "/v2/vmActions": { + "post": { + "description": "Creates a new action", + "parameters": [ + { + "description": "VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmActionCreate" } + } + }, + "description": "actions body", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.VmActionCreated" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Creates a new action", + "tags": ["VmAction"] + } + }, + "/v2/vms": { + "get": { + "description": "List VMs", + "parameters": [ + { + "description": "List all", + "in": "query", + "name": "all", + "schema": { "type": "boolean" } + }, + { + "description": "Filter by user ID", + "in": "query", + "name": "userId", + "schema": { "type": "string" } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "schema": { "type": "integer" } + }, + { + "description": "Number of items per page", + "in": "query", + "name": "pageSize", + "schema": { "type": "integer" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.VmRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List VMs", + "tags": ["VM"] + }, + "post": { + "description": "Create VM", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmCreate" } + } + }, + "description": "VM body", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmCreated" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Create VM", + "tags": ["VM"] + } + }, + "/v2/vms/{vmId}": { + "delete": { + "description": "Delete VM", + "parameters": [ + { + "description": "VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmDeleted" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete VM", + "tags": ["VM"] + }, + "get": { + "description": "Get VM", + "parameters": [ + { + "description": "VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get VM", + "tags": ["VM"] + }, + "post": { + "description": "Update VM", + "parameters": [ + { + "description": "VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmUpdate" } + } + }, + "description": "VM update", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmUpdated" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "401": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Unauthorized" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Update VM", + "tags": ["VM"] + } + }, + "/v2/vms/{vmId}/snapshot/{snapshotId}": { + "delete": { + "description": "Delete snapshot", + "parameters": [ + { + "description": "VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + }, + { + "description": "Snapshot ID", + "in": "path", + "name": "snapshotId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/body.VmSnapshotDeleted" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Delete snapshot", + "tags": ["Snapshot"] + }, + "post": { + "description": "Get snapshot", + "parameters": [ + { + "description": "VM ID", + "in": "path", + "name": "vmId", + "required": true, + "schema": { "type": "string" } + }, + { + "description": "Snapshot ID", + "in": "path", + "name": "snapshotId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/body.VmSnapshotRead" } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Not Found" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "Get snapshot", + "tags": ["Snapshot"] + } + }, + "/v2/workerStatus": { + "get": { + "description": "List of worker status", + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/body.WorkerStatusRead" + }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "summary": "List worker status", + "tags": ["Status"] + } + }, + "/v2/zones": { + "get": { + "description": "List zones", + "requestBody": { + "content": { "application/json": { "schema": { "type": "object" } } } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { "$ref": "#/components/schemas/body.ZoneRead" }, + "type": "array" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Bad Request" + }, + "500": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } + } + }, + "description": "Internal Server Error" + } + }, + "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], + "summary": "List zones", + "tags": ["Zone"] + } + } + }, + "openapi": "3.1.0" +} diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index c9c52eae..e74e17a3 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -1,2529 +1,105 @@ -openapi: 3.0.1 -info: - title: go-deploy API - description: This is the API explorer for the go-deploy API. You can use it as a - reference for the API endpoints. - termsOfService: http://swagger.io/terms/ - contact: - name: Support - url: https://github.com/kthcloud/go-deploy - license: - name: MIT License - url: https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme - version: "1.0" -servers: -- url: / -paths: - /v2/deployments: - get: - tags: - - Deployment - summary: List deployments - description: List deployments - parameters: - - name: all - in: query - description: List all - schema: - type: boolean - - name: userId - in: query - description: Filter by user ID - schema: +components: + schemas: + body.ApiKey: + properties: + createdAt: type: string - - name: shared - in: query - description: Include shared - schema: - type: boolean - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.DeploymentRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - Deployment - summary: Create deployment - description: Create deployment - requestBody: - description: Deployment body - content: - application/json: - schema: - $ref: '#/components/schemas/body.DeploymentCreate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.DeploymentRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/deployments/{deploymentId}: - get: - tags: - - Deployment - summary: Get deployment - description: Get deployment - parameters: - - name: deploymentId - in: path - description: Deployment ID - required: true - schema: + expiresAt: type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.DeploymentRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - Deployment - summary: Update deployment - description: Update deployment - parameters: - - name: deploymentId - in: path - description: Deployment ID - required: true - schema: + name: type: string - requestBody: - description: Deployment update - content: - application/json: - schema: - $ref: '#/components/schemas/body.DeploymentUpdate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.DeploymentUpdated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - delete: - tags: - - Deployment - summary: Delete deployment - description: Delete deployment - parameters: - - name: deploymentId - in: path - description: Deployment ID - required: true - schema: + type: object + body.ApiKeyCreate: + properties: + expiresAt: type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.DeploymentCreated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/deployments/{deploymentId}/ciConfig: - get: - tags: - - Deployment - summary: Get CI config - description: Get CI config - parameters: - - name: deploymentId - in: path - description: Deployment ID - required: true - schema: + name: type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.CiConfig' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/deployments/{deploymentId}/command: - post: - tags: - - Deployment - summary: Do command - description: Do command - parameters: - - name: deploymentId - in: path - description: Deployment ID - required: true - schema: + required: + - expiresAt + - name + type: object + body.ApiKeyCreated: + properties: + createdAt: type: string - requestBody: - description: Command body - content: - application/json: - schema: - $ref: '#/components/schemas/body.DeploymentCommand' - required: true - responses: - "204": - description: No Content - content: {} - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "423": - description: Locked - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/deployments/{deploymentId}/logs: - get: - tags: - - Deployment - summary: Get logs using Server-Sent Events - description: Get logs using Server-Sent Events - parameters: - - name: deploymentId - in: path - description: Deployment ID - required: true - schema: + expiresAt: type: string - responses: - "200": - description: OK - content: - application/json: - schema: - type: string - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/discover: - get: - tags: - - Discover - summary: Discover - description: Discover - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.DiscoverRead' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/gpuGroups: - get: - tags: - - GpuGroup - summary: List GPU groups - description: List GPU groups - parameters: - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.GpuGroupRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "423": - description: Locked - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/gpuGroups/{gpuGroupId}: - get: - tags: - - GpuGroup - summary: Get GPU group - description: Get GPU group - parameters: - - name: gpuGroupId - in: path - description: GPU group ID - required: true - schema: + key: type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.GpuGroupRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "423": - description: Locked - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/gpuLeases: - get: - tags: - - GpuLease - summary: List GPU leases - description: List GPU leases - parameters: - - name: all - in: query - description: List all - schema: - type: boolean - - name: vmId - in: query - description: Filter by VM ID - schema: + name: type: string - - name: page - in: query - description: Page number - schema: + type: object + body.BindingError: + properties: + validationErrors: + additionalProperties: + items: + type: string + type: array + type: object + type: object + body.CiConfig: + properties: + config: + type: string + type: object + body.ClusterCapacities: + properties: + cluster: + type: string + cpuCore: + $ref: '#/components/schemas/body.CpuCoreCapacities' + gpu: + $ref: '#/components/schemas/body.GpuCapacities' + ram: + $ref: '#/components/schemas/body.RamCapacities' + type: object + body.ClusterStats: + properties: + cluster: + type: string + podCount: type: integer - - name: pageSize - in: query - description: Number of items per page - schema: + type: object + body.CpuCoreCapacities: + description: Total + properties: + total: type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.GpuLeaseRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "423": - description: Locked - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - GpuLease - summary: Create GPU Lease - description: Create GPU lease - requestBody: - description: GPU lease - content: - application/json: - schema: - $ref: '#/components/schemas/body.GpuLeaseCreate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.GpuLeaseCreated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/gpuLeases/{gpuLeaseId}: - get: - tags: - - GpuLease - summary: Get GPU lease - description: Get GPU lease - parameters: - - name: gpuLeaseId - in: path - description: GPU lease ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.GpuLeaseRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "423": - description: Locked - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - GpuLease - summary: Update GPU lease - description: Update GPU lease - parameters: - - name: gpuLeaseId - in: path - description: GPU lease ID - required: true - schema: - type: string - requestBody: - description: GPU lease - content: - application/json: - schema: - $ref: '#/components/schemas/body.GpuLeaseUpdate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.GpuLeaseUpdated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - delete: - tags: - - GpuLease - summary: Delete GPU lease - description: Delete GPU lease - parameters: - - name: gpuLeaseId - in: path - description: GPU lease ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.GpuLeaseDeleted' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/hooks/harbor: - post: - tags: - - Deployment - summary: Handle Harbor hook - description: Handle Harbor hook - parameters: - - name: Authorization - in: header - description: Basic auth token - schema: - type: string - requestBody: - description: Harbor webhook body - content: - application/json: - schema: - $ref: '#/components/schemas/body.HarborWebhook' - required: true - responses: - "204": - description: No Content - content: {} - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - x-codegen-request-body-name: body - /v2/hosts: - get: - tags: - - Host - summary: List Hosts - description: List Hosts - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.HostRead' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/jobs: - get: - tags: - - Job - summary: List jobs - description: List jobs - parameters: - - name: all - in: query - description: List all - schema: - type: boolean - - name: userId - in: query - description: Filter by user ID - schema: - type: string - - name: type - in: query - description: Filter by type - schema: - type: string - - name: status - in: query - description: Filter by status - schema: - type: string - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.JobRead' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/jobs/{jobId}: - get: - tags: - - Job - summary: GetJob job by id - description: GetJob job by id - parameters: - - name: jobId - in: path - description: Job ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.JobRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - Job - summary: Update job - description: Update job. Only allowed for admins. - parameters: - - name: jobId - in: path - description: Job ID - required: true - schema: - type: string - requestBody: - description: Job update - content: - application/json: - schema: - $ref: '#/components/schemas/body.JobUpdate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.JobRead' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/metrics: - get: - tags: - - Metrics - summary: Get metrics - description: Get metrics - responses: - "200": - description: OK - content: - application/json: - schema: - type: string - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/notifications: - get: - tags: - - Notification - summary: List notifications - description: List notifications - parameters: - - name: all - in: query - description: List all notifications - schema: - type: boolean - - name: userId - in: query - description: Filter by user ID - schema: - type: string - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.NotificationRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/notifications/{notificationId}: - get: - tags: - - Notification - summary: Get notification - description: Get notification - parameters: - - name: notificationId - in: path - description: Notification ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.NotificationRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - Notification - summary: Update notification - description: Update notification - parameters: - - name: notificationId - in: path - description: Notification ID - required: true - schema: - type: string - requestBody: - description: Notification update - content: - application/json: - schema: - $ref: '#/components/schemas/body.NotificationUpdate' - required: true - responses: - "200": - description: OK - content: {} - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - delete: - tags: - - Notification - summary: Delete notification - description: Delete notification - parameters: - - name: notificationId - in: path - description: Notification ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: {} - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/register: - get: - tags: - - Register - summary: Register resource - description: Register resource - responses: - "204": - description: No Content - content: {} - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/resourceMigrations: - get: - tags: - - ResourceMigration - summary: List resource migrations - description: List resource migrations - parameters: - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.ResourceMigrationRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - ResourceMigration - summary: Create resource migration - description: Create resource migration - requestBody: - description: Resource Migration Create - content: - application/json: - schema: - $ref: '#/components/schemas/body.ResourceMigrationCreate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.ResourceMigrationCreated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/resourceMigrations/{resourceMigrationId}: - get: - tags: - - ResourceMigration - summary: Get resource migration - description: Get resource migration - parameters: - - name: resourceMigrationId - in: path - description: Resource Migration ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.ResourceMigrationRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - ResourceMigration - summary: Update resource migration - description: Update resource migration - parameters: - - name: resourceMigrationId - in: path - description: Resource Migration ID - required: true - schema: - type: string - requestBody: - description: Resource Migration Update - content: - application/json: - schema: - $ref: '#/components/schemas/body.ResourceMigrationUpdate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.ResourceMigrationUpdated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - delete: - tags: - - ResourceMigration - summary: Delete resource migration - description: Delete resource migration - parameters: - - name: resourceMigrationId - in: path - description: Resource Migration ID - required: true - schema: - type: string - responses: - "204": - description: No Content - content: {} - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/snapshots: - get: - tags: - - Snapshot - summary: List snapshots - description: List snapshots - parameters: - - name: vmId - in: path - description: Filter by VM ID - required: true - schema: - type: string - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.VmSnapshotRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "423": - description: Locked - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - Snapshot - summary: Create snapshot - description: Create snapshot - parameters: - - name: vmId - in: path - description: VM ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmSnapshotCreated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/storageManagers: - get: - tags: - - StorageManager - summary: Get storage manager list - description: Get storage manager list - parameters: - - name: all - in: query - description: List all - schema: - type: boolean - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.SmRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/storageManagers/{storageManagerId}: - get: - tags: - - StorageManager - summary: Delete storage manager - description: Delete storage manager - parameters: - - name: storageManagerId - in: path - description: Storage manager ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.SmDeleted' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/systemCapacities: - get: - tags: - - System - summary: List system capacities - description: List system capacities - parameters: - - name: "n" - in: query - description: "n" - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.TimestampedSystemCapacities' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/systemStats: - get: - tags: - - System - summary: List system stats - description: List system stats - parameters: - - name: "n" - in: query - description: "n" - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.TimestampedSystemStats' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/systemStatus: - get: - tags: - - System - summary: List system stats - description: List system stats - parameters: - - name: "n" - in: query - description: "n" - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.TimestampedSystemStatus' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/teams: - get: - tags: - - Team - summary: List teams - description: List teams - parameters: - - name: all - in: query - description: List all - schema: - type: boolean - - name: userId - in: query - description: Filter by user ID - schema: - type: string - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.TeamRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - Team - summary: Create team - description: Create team - requestBody: - description: Team - content: - application/json: - schema: - $ref: '#/components/schemas/body.TeamCreate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.TeamRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/teams/{teamId}: - get: - tags: - - Team - summary: Get team - description: Get team - parameters: - - name: teamId - in: path - description: Team ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.TeamRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - Team - summary: Update team - description: Update team - parameters: - - name: teamId - in: path - description: Team ID - required: true - schema: - type: string - requestBody: - description: Team - content: - application/json: - schema: - $ref: '#/components/schemas/body.TeamUpdate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.TeamRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - delete: - tags: - - Team - summary: Delete team - description: Delete team - parameters: - - name: teamId - in: path - description: Team ID - required: true - schema: - type: string - responses: - "204": - description: No Content - content: {} - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/body.BindingError' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/users: - get: - tags: - - User - summary: List users - description: List users - parameters: - - name: all - in: query - description: List all - schema: - type: boolean - - name: discover - in: query - description: Discovery mode - schema: - type: boolean - - name: search - in: query - description: Search query - schema: - type: string - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.UserRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/users/{userId}: - get: - tags: - - User - summary: Get user - description: Get user - parameters: - - name: userId - in: path - description: User ID - required: true - schema: - type: string - - name: discover - in: query - description: Discovery mode - schema: - type: boolean - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.UserRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - User - summary: Update user - description: Update user - parameters: - - name: userId - in: path - description: User ID - required: true - schema: - type: string - requestBody: - description: User update - content: - application/json: - schema: - $ref: '#/components/schemas/body.UserUpdate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.UserRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/users/{userId}/apiKeys: - post: - tags: - - User - summary: Create API key - description: Create API key - parameters: - - name: userId - in: path - description: User ID - required: true - schema: - type: string - requestBody: - description: API key create body - content: - application/json: - schema: - $ref: '#/components/schemas/body.ApiKeyCreate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.ApiKeyCreated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/vmActions: - post: - tags: - - VmAction - summary: Creates a new action - description: Creates a new action - parameters: - - name: vmId - in: path - description: VM ID - required: true - schema: - type: string - requestBody: - description: actions body - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmActionCreate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmActionCreated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/vms: - get: - tags: - - VM - summary: List VMs - description: List VMs - parameters: - - name: all - in: query - description: List all - schema: - type: boolean - - name: userId - in: query - description: Filter by user ID - schema: - type: string - - name: page - in: query - description: Page number - schema: - type: integer - - name: pageSize - in: query - description: Number of items per page - schema: - type: integer - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.VmRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - VM - summary: Create VM - description: Create VM - requestBody: - description: VM body - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmCreate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmCreated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - /v2/vms/{vmId}: - get: - tags: - - VM - summary: Get VM - description: Get VM - parameters: - - name: vmId - in: path - description: VM ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - post: - tags: - - VM - summary: Update VM - description: Update VM - parameters: - - name: vmId - in: path - description: VM ID - required: true - schema: - type: string - requestBody: - description: VM update - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmUpdate' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmUpdated' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - x-codegen-request-body-name: body - delete: - tags: - - VM - summary: Delete VM - description: Delete VM - parameters: - - name: vmId - in: path - description: VM ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmDeleted' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/vms/{vmId}/snapshot/{snapshotId}: - post: - tags: - - Snapshot - summary: Get snapshot - description: Get snapshot - parameters: - - name: vmId - in: path - description: VM ID - required: true - schema: - type: string - - name: snapshotId - in: path - description: Snapshot ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmSnapshotRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - delete: - tags: - - Snapshot - summary: Delete snapshot - description: Delete snapshot - parameters: - - name: vmId - in: path - description: VM ID - required: true - schema: - type: string - - name: snapshotId - in: path - description: Snapshot ID - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/body.VmSnapshotDeleted' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] - /v2/workerStatus: - get: - tags: - - Status - summary: List worker status - description: List of worker status - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.WorkerStatusRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - /v2/zones: - get: - tags: - - Zone - summary: List zones - description: List zones - responses: - "200": - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/body.ZoneRead' - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - "500": - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/sys.ErrorResponse' - security: - - ApiKeyAuth: [] - - KeycloakOAuth: [] -components: - schemas: - body.ApiKey: - type: object - properties: - createdAt: - type: string - expiresAt: - type: string - name: - type: string - body.ApiKeyCreate: - required: - - expiresAt - - name - type: object - properties: - expiresAt: - type: string - name: - type: string - body.ApiKeyCreated: - type: object - properties: - createdAt: - type: string - expiresAt: - type: string - key: - type: string - name: - type: string - body.BindingError: - type: object - properties: - validationErrors: - type: object - additionalProperties: - type: array - items: - type: string - body.CiConfig: - type: object - properties: - config: - type: string - body.ClusterCapacities: - type: object - properties: - cluster: - type: string - cpuCore: - $ref: '#/components/schemas/body.CpuCoreCapacities' - gpu: - $ref: '#/components/schemas/body.GpuCapacities' - ram: - $ref: '#/components/schemas/body.RamCapacities' - body.ClusterStats: - type: object - properties: - cluster: - type: string - podCount: - type: integer - body.CpuCoreCapacities: type: object - properties: - total: - type: integer body.CpuStatus: - type: object properties: load: $ref: '#/components/schemas/body.CpuStatusLoad' temp: $ref: '#/components/schemas/body.CpuStatusTemp' - body.CpuStatusLoad: type: object + body.CpuStatusLoad: properties: cores: - type: array items: type: integer + type: array + uniqueItems: false main: type: number max: type: number - body.CpuStatusTemp: type: object + body.CpuStatusTemp: properties: cores: - type: array items: type: integer + type: array + uniqueItems: false main: type: number max: type: number - body.CustomDomainRead: type: object + body.CustomDomainRead: properties: domain: type: string @@ -2533,40 +109,211 @@ components: type: string url: type: string + type: object body.DeploymentCommand: + properties: + command: + enum: + - restart + type: string required: - command type: object + body.DeploymentCreate: properties: - command: + args: + items: + type: string + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false + cpuCores: + type: number + customDomain: + description: |- + CustomDomain is the domain that the deployment will be available on. + The max length is set to 243 to allow for a subdomain when confirming the domain. + type: string + envs: + items: + $ref: '#/components/schemas/body.Env' + maxItems: 1000 + minItems: 0 + type: array + uniqueItems: false + healthCheckPath: + maxLength: 1000 + minLength: 0 + type: string + image: + maxLength: 1000 + minLength: 1 + type: string + initCommands: + items: + type: string + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false + name: + maxLength: 30 + minLength: 3 type: string + private: + description: 'Deprecated: Use Visibility instead.' + type: boolean + ram: + type: number + replicas: + maximum: 100 + minimum: 0 + type: integer + visibility: enum: - - restart - body.DeploymentCreate: + - public + - private + - auth + type: string + volumes: + items: + $ref: '#/components/schemas/body.Volume' + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false + zone: + description: |- + Zone is the zone that the deployment will be created in. + If the zone is not set, the deployment will be created in the default zone. + type: string required: - name type: object + body.DeploymentCreated: + properties: + id: + type: string + jobId: + type: string + type: object + body.DeploymentRead: properties: + accessedAt: + type: string args: - maxItems: 100 - minItems: 0 + items: + type: string + type: array + uniqueItems: false + createdAt: + type: string + customDomain: + $ref: '#/components/schemas/body.CustomDomainRead' + envs: + items: + $ref: '#/components/schemas/body.Env' + type: array + uniqueItems: false + error: + type: string + healthCheckPath: + type: string + id: + type: string + image: + type: string + initCommands: + items: + type: string + type: array + uniqueItems: false + integrations: + description: |- + Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment + + For example GitHub + items: + type: string + type: array + uniqueItems: false + internalPort: + type: integer + name: + type: string + ownerId: + type: string + pingResult: + type: integer + private: + description: 'Deprecated: Use Visibility instead.' + type: boolean + repairedAt: + type: string + replicaStatus: + $ref: '#/components/schemas/body.ReplicaStatus' + restartedAt: + type: string + specs: + $ref: '#/components/schemas/body.DeploymentSpecs' + status: + type: string + storageUrl: + type: string + teams: + items: + type: string + type: array + uniqueItems: false + type: + type: string + updatedAt: + type: string + url: + type: string + visibility: + type: string + volumes: + items: + $ref: '#/components/schemas/body.Volume' type: array + uniqueItems: false + zone: + type: string + type: object + body.DeploymentSpecs: + properties: + cpuCores: + type: number + ram: + type: number + replicas: + type: integer + type: object + body.DeploymentUpdate: + properties: + args: items: type: string + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false cpuCores: - minimum: 0.1 type: number customDomain: - type: string description: |- CustomDomain is the domain that the deployment will be available on. The max length is set to 243 to allow for a subdomain when confirming the domain. + type: string envs: + items: + $ref: '#/components/schemas/body.Env' maxItems: 1000 minItems: 0 type: array - items: - $ref: '#/components/schemas/body.Env' + uniqueItems: false healthCheckPath: maxLength: 1000 minLength: 0 @@ -2575,1427 +322,3898 @@ components: maxLength: 1000 minLength: 1 type: string - initCommands: - maxItems: 100 - minItems: 0 - type: array - items: - type: string + initCommands: + items: + type: string + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false + name: + maxLength: 30 + minLength: 3 + type: string + private: + description: 'Deprecated: Use Visibility instead.' + type: boolean + ram: + type: number + replicas: + maximum: 100 + minimum: 0 + type: integer + visibility: + enum: + - public + - private + - auth + type: string + volumes: + items: + $ref: '#/components/schemas/body.Volume' + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false + required: + - name + type: object + body.DeploymentUpdated: + properties: + id: + type: string + jobId: + type: string + type: object + body.DiscoverRead: + properties: + roles: + items: + $ref: '#/components/schemas/body.Role' + type: array + uniqueItems: false + version: + type: string + type: object + body.Env: + properties: + name: + maxLength: 100 + minLength: 1 + type: string + value: + maxLength: 10000 + minLength: 1 + type: string + required: + - name + - value + type: object + body.GpuCapacities: + properties: + total: + type: integer + type: object + body.GpuGroupRead: + properties: + available: + type: integer + displayName: + type: string + id: + type: string name: - maxLength: 30 - minLength: 3 type: string - private: - type: boolean - description: "Deprecated: Use Visibility instead." - ram: - minimum: 0.1 - type: number - replicas: - maximum: 100 - minimum: 0 + total: type: integer - visibility: + vendor: type: string - enum: - - public - - private - - auth - volumes: - maxItems: 100 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.Volume' zone: type: string + type: object + body.GpuLeaseCreate: + properties: + gpuGroupId: description: |- - Zone is the zone that the deployment will be created in. - If the zone is not set, the deployment will be created in the default zone. - body.DeploymentCreated: + GpuGroupID is used to specify the GPU to lease. + As such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease. + type: string + leaseForever: + description: LeaseForever is used to specify whether the lease should be + created forever. + type: boolean + required: + - gpuGroupId type: object + body.GpuLeaseCreated: properties: id: type: string jobId: type: string - body.DeploymentRead: type: object + body.GpuLeaseDeleted: properties: - accessedAt: + id: + type: string + jobId: + type: string + type: object + body.GpuLeaseRead: + properties: + activatedAt: + description: |- + ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU + or 1 day after the lease was created if the user did not attach the GPU. + type: string + active: + type: boolean + assignedAt: + description: AssignedAt specifies the time when the lease was assigned to + the user. type: string - args: - type: array - items: - type: string createdAt: type: string - customDomain: - $ref: '#/components/schemas/body.CustomDomainRead' - envs: - type: array - items: - $ref: '#/components/schemas/body.Env' - error: + expiredAt: type: string - healthCheckPath: + expiresAt: + description: |- + ExpiresAt specifies the time when the lease will expire. + This is only present if the lease is active. + type: string + gpuGroupId: type: string id: type: string - image: + leaseDuration: + type: number + queuePosition: + type: integer + userId: type: string - initCommands: - type: array - items: - type: string - integrations: - type: array + vmId: + description: VmID is set when the lease is attached to a VM. + type: string + type: object + body.GpuLeaseUpdate: + properties: + vmId: description: |- - Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment + VmID is used to specify the VM to attach the lease to. - For example GitHub + - If specified, the lease will be attached to the VM. + + - If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM. + + - If the lease is not active, specifying a VM will activate the lease. + + - If the lease is not assigned, an error will be returned. + type: string + type: object + body.GpuLeaseUpdated: + properties: + id: + type: string + jobId: + type: string + type: object + body.GpuStatus: + properties: + temp: items: - type: string - internalPort: + $ref: '#/components/schemas/body.GpuStatusTemp' + type: array + uniqueItems: false + type: object + body.GpuStatusTemp: + properties: + main: + type: number + type: object + body.HarborWebhook: + properties: + event_data: + properties: + repository: + properties: + date_created: + type: integer + name: + type: string + namespace: + type: string + repo_full_name: + type: string + repo_type: + type: string + type: object + resources: + items: + properties: + digest: + type: string + resource_url: + type: string + tag: + type: string + type: object + type: array + uniqueItems: false + type: object + occur_at: type: integer - name: + operator: type: string - ownerId: + type: type: string - pingResult: - type: integer - private: - type: boolean - description: "Deprecated: Use Visibility instead." - repairedAt: + type: object + body.HostCapacities: + properties: + cpuCore: + $ref: '#/components/schemas/body.CpuCoreCapacities' + displayName: type: string - replicaStatus: - $ref: '#/components/schemas/body.ReplicaStatus' - restartedAt: + gpu: + $ref: '#/components/schemas/body.GpuCapacities' + name: type: string - specs: - $ref: '#/components/schemas/body.DeploymentSpecs' - status: + ram: + $ref: '#/components/schemas/body.RamCapacities' + zone: + description: Zone is the name of the zone where the host is located. type: string - storageUrl: + type: object + body.HostRead: + properties: + displayName: type: string - teams: - type: array - items: - type: string - type: + name: type: string - updatedAt: + zone: + description: Zone is the name of the zone where the host is located. type: string - url: + type: object + body.HostStatus: + properties: + cpu: + $ref: '#/components/schemas/body.CpuStatus' + displayName: type: string - visibility: + gpu: + $ref: '#/components/schemas/body.GpuStatus' + name: type: string - volumes: - type: array - items: - $ref: '#/components/schemas/body.Volume' + ram: + $ref: '#/components/schemas/body.RamStatus' zone: + description: Zone is the name of the zone where the host is located. type: string - body.DeploymentSpecs: type: object + body.HttpProxyCreate: properties: - cpuCores: - type: number - ram: - type: number - replicas: - type: integer - body.DeploymentUpdate: + customDomain: + description: |- + CustomDomain is the domain that the deployment will be available on. + The max length is set to 243 to allow for a subdomain when confirming the domain. + type: string + name: + maxLength: 30 + minLength: 3 + type: string required: - name type: object + body.HttpProxyRead: properties: - args: - maxItems: 100 - minItems: 0 - type: array - items: - type: string - cpuCores: - minimum: 0.1 - type: number customDomain: + $ref: '#/components/schemas/body.CustomDomainRead' + name: + type: string + url: type: string + type: object + body.HttpProxyUpdate: + properties: + customDomain: description: |- CustomDomain is the domain that the deployment will be available on. The max length is set to 243 to allow for a subdomain when confirming the domain. - envs: - maxItems: 1000 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.Env' - healthCheckPath: - maxLength: 1000 - minLength: 0 type: string - image: - maxLength: 1000 - minLength: 1 - type: string - initCommands: - maxItems: 100 - minItems: 0 - type: array - items: - type: string name: maxLength: 30 minLength: 3 type: string - private: - type: boolean - description: "Deprecated: Use Visibility instead." - ram: - minimum: 0.1 - type: number - replicas: - maximum: 100 - minimum: 0 - type: integer - visibility: + required: + - name + type: object + body.JobRead: + properties: + createdAt: + type: string + finishedAt: + type: string + id: + type: string + lastError: + type: string + lastRunAt: + type: string + runAfter: + type: string + status: + type: string + type: + type: string + userId: type: string + type: object + body.JobUpdate: + properties: + status: enum: - - public - - private - - auth - volumes: - maxItems: 100 - minItems: 0 - type: array + - pending + - running + - failed + - terminated + - finished + - completed + type: string + type: object + body.K8sStats: + properties: + clusters: items: - $ref: '#/components/schemas/body.Volume' - body.DeploymentUpdated: + $ref: '#/components/schemas/body.ClusterStats' + type: array + uniqueItems: false + podCount: + type: integer type: object + body.NotificationRead: properties: + completedAt: + type: string + content: + additionalProperties: {} + type: object + createdAt: + type: string id: type: string - jobId: + readAt: + type: string + toastedAt: + type: string + type: + type: string + userId: type: string - body.DiscoverRead: type: object + body.NotificationUpdate: properties: - roles: - type: array - items: - $ref: '#/components/schemas/body.Role' - version: + read: + type: boolean + toasted: + type: boolean + type: object + body.PortCreate: + properties: + httpProxy: + $ref: '#/components/schemas/body.HttpProxyCreate' + name: + maxLength: 100 + minLength: 1 + type: string + port: + maximum: 65535 + minimum: 1 + type: integer + protocol: + enum: + - tcp + - udp type: string - body.Env: required: - name - - value + - port + - protocol + type: object + body.PortRead: + properties: + externalPort: + type: integer + httpProxy: + $ref: '#/components/schemas/body.HttpProxyRead' + name: + type: string + port: + type: integer + protocol: + type: string type: object + body.PortUpdate: properties: + httpProxy: + $ref: '#/components/schemas/body.HttpProxyUpdate' name: maxLength: 100 minLength: 1 type: string - value: - maxLength: 10000 + port: + maximum: 65535 + minimum: 1 + type: integer + protocol: + enum: + - tcp + - udp + type: string + required: + - name + - port + - protocol + type: object + body.PublicKey: + properties: + key: + type: string + name: + maxLength: 30 minLength: 1 type: string - body.GpuCapacities: + required: + - key + - name + type: object + body.Quota: + properties: + cpuCores: + type: number + diskSize: + type: number + gpuLeaseDuration: + description: in hours + type: number + ram: + type: number + snapshots: + type: integer type: object + body.RamCapacities: properties: total: type: integer - body.GpuGroupRead: type: object + body.RamStatus: + properties: + load: + $ref: '#/components/schemas/body.RamStatusLoad' + type: object + body.RamStatusLoad: + properties: + main: + type: number + type: object + body.ReplicaStatus: + properties: + availableReplicas: + description: AvailableReplicas is the number of replicas that are available. + type: integer + desiredReplicas: + description: DesiredReplicas is the number of replicas that the deployment + should have. + type: integer + readyReplicas: + description: ReadyReplicas is the number of replicas that are ready. + type: integer + unavailableReplicas: + description: UnavailableReplicas is the number of replicas that are unavailable. + type: integer + type: object + body.ResourceMigrationCreate: + properties: + resourceId: + description: |- + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. + type: string + status: + description: |- + Status is the status of the resource migration. + It is used by privileged admins to directly accept or reject a migration. + The field is ignored by non-admins. + + Possible values: + - accepted + - pending + type: string + type: + description: |- + Type is the type of the resource migration. + + Possible values: + - updateOwner + enum: + - updateOwner + type: string + updateOwner: + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is ignored if the migration type is not updateOwner. + properties: + ownerId: + type: string + required: + - ownerId + type: object + required: + - resourceId + - type + type: object + body.ResourceMigrationCreated: properties: - available: - type: integer - displayName: + createdAt: + type: string + deletedAt: type: string id: type: string - name: + jobId: + description: |- + JobID is the ID of the job that was created for the resource migration. + It will only be set if the migration was created with status 'accepted'. type: string - total: - type: integer - vendor: + resourceId: + description: |- + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. type: string - zone: + resourceType: + description: |- + ResourceType is the type of the resource that is being migrated. + + Possible values: + - vm + - deployment type: string - body.GpuLeaseCreate: - required: - - gpuGroupId - type: object - properties: - gpuGroupId: + status: + description: |- + Status is the status of the resource migration. + When this field is set to 'accepted', the migration will take place and then automatically be deleted. type: string + type: description: |- - GpuGroupID is used to specify the GPU to lease. - As such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease. - leaseForever: - type: boolean - description: LeaseForever is used to specify whether the lease should be - created forever. - body.GpuLeaseCreated: - type: object - properties: - id: + Type is the type of the resource migration. + + Possible values: + - updateOwner type: string - jobId: + updateOwner: + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is empty if the migration type is not updateOwner. + properties: + ownerId: + type: string + type: object + userId: + description: UserID is the ID of the user who initiated the migration. type: string - body.GpuLeaseDeleted: type: object + body.ResourceMigrationRead: properties: - id: + createdAt: type: string - jobId: + deletedAt: type: string - body.GpuLeaseRead: - type: object - properties: - activatedAt: + id: type: string + resourceId: description: |- - ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU - or 1 day after the lease was created if the user did not attach the GPU. - active: - type: boolean - assignedAt: - type: string - description: AssignedAt specifies the time when the lease was assigned to - the user. - createdAt: - type: string - expiredAt: + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. type: string - expiresAt: + resourceType: + description: |- + ResourceType is the type of the resource that is being migrated. + + Possible values: + - vm + - deployment type: string + status: description: |- - ExpiresAt specifies the time when the lease will expire. - This is only present if the lease is active. - gpuGroupId: + Status is the status of the resource migration. + When this field is set to 'accepted', the migration will take place and then automatically be deleted. type: string - id: + type: + description: |- + Type is the type of the resource migration. + + Possible values: + - updateOwner type: string - leaseDuration: - type: number - queuePosition: - type: integer + updateOwner: + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is empty if the migration type is not updateOwner. + properties: + ownerId: + type: string + type: object userId: + description: UserID is the ID of the user who initiated the migration. type: string - vmId: - type: string - description: VmID is set when the lease is attached to a VM. - body.GpuLeaseUpdate: type: object + body.ResourceMigrationUpdate: properties: - vmId: + code: + description: |- + Code is a token required when accepting a migration if the acceptor is not an admin. + It is sent to the acceptor using the notification API type: string + status: description: |- - VmID is used to specify the VM to attach the lease to. - - - If specified, the lease will be attached to the VM. - - - If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM. - - - If the lease is not active, specifying a VM will activate the lease. + Status is the status of the resource migration. + It is used to accept a migration by setting the status to 'accepted'. + If the acceptor is not an admin, a Code must be provided. - - If the lease is not assigned, an error will be returned. - body.GpuLeaseUpdated: + Possible values: + - accepted + - pending + type: string + required: + - status type: object + body.ResourceMigrationUpdated: properties: + createdAt: + type: string + deletedAt: + type: string id: type: string jobId: + description: |- + JobID is the ID of the job that was created for the resource migration. + It will only be set if the migration was updated with status 'accepted'. + type: string + resourceId: + description: |- + ResourceID is the ID of the resource that is being migrated. + This can be a VM ID, deployment ID, etc. depending on the type of the migration. + type: string + resourceType: + description: |- + ResourceType is the type of the resource that is being migrated. + + Possible values: + - vm + - deployment + type: string + status: + description: |- + Status is the status of the resource migration. + When this field is set to 'accepted', the migration will take place and then automatically be deleted. + type: string + type: + description: |- + Type is the type of the resource migration. + + Possible values: + - updateOwner + type: string + updateOwner: + description: |- + UpdateOwner is the set of parameters that are required for the updateOwner migration type. + It is empty if the migration type is not updateOwner. + properties: + ownerId: + type: string + type: object + userId: + description: UserID is the ID of the user who initiated the migration. type: string - body.GpuStatus: type: object + body.Role: properties: - temp: - type: array + description: + type: string + name: + type: string + permissions: items: - $ref: '#/components/schemas/body.GpuStatusTemp' - body.GpuStatusTemp: + type: string + type: array + uniqueItems: false + quota: + $ref: '#/components/schemas/body.Quota' type: object + body.SmDeleted: properties: - main: - type: number - body.HarborWebhook: + id: + type: string + jobId: + type: string type: object + body.SmRead: properties: - event_data: - type: object - properties: - repository: - type: object - properties: - date_created: - type: integer - name: - type: string - namespace: - type: string - repo_full_name: - type: string - repo_type: - type: string - resources: - type: array - items: - type: object - properties: - digest: - type: string - resource_url: - type: string - tag: - type: string - occur_at: - type: integer - operator: + createdAt: + type: string + id: + type: string + ownerId: + type: string + url: type: string - type: + zone: type: string - body.HostCapacities: type: object + body.SystemCapacities: properties: + clusters: + description: Per Cluster + items: + $ref: '#/components/schemas/body.ClusterCapacities' + type: array + uniqueItems: false cpuCore: $ref: '#/components/schemas/body.CpuCoreCapacities' - displayName: - type: string gpu: $ref: '#/components/schemas/body.GpuCapacities' - name: - type: string + hosts: + description: Per Host + items: + $ref: '#/components/schemas/body.HostCapacities' + type: array + uniqueItems: false ram: $ref: '#/components/schemas/body.RamCapacities' - zone: - type: string - description: Zone is the name of the zone where the host is located. - body.HostRead: type: object + body.SystemStats: properties: - displayName: - type: string - name: - type: string - zone: - type: string - description: Zone is the name of the zone where the host is located. - body.HostStatus: + k8s: + $ref: '#/components/schemas/body.K8sStats' type: object + body.SystemStatus: properties: - cpu: - $ref: '#/components/schemas/body.CpuStatus' - displayName: - type: string - gpu: - $ref: '#/components/schemas/body.GpuStatus' - name: - type: string - ram: - $ref: '#/components/schemas/body.RamStatus' - zone: - type: string - description: Zone is the name of the zone where the host is located. - body.HttpProxyCreate: - required: - - name + hosts: + items: + $ref: '#/components/schemas/body.HostStatus' + type: array + uniqueItems: false type: object + body.TeamCreate: properties: - customDomain: - type: string - description: |- - CustomDomain is the domain that the deployment will be available on. - The max length is set to 243 to allow for a subdomain when confirming the domain. - name: - maxLength: 30 - minLength: 3 + description: + maxLength: 1000 type: string - body.HttpProxyRead: - type: object - properties: - customDomain: - $ref: '#/components/schemas/body.CustomDomainRead' + members: + items: + $ref: '#/components/schemas/body.TeamMemberCreate' + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false name: + maxLength: 100 + minLength: 1 type: string - url: - type: string - body.HttpProxyUpdate: + resources: + items: + type: string + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false required: - name type: object + body.TeamMember: properties: - customDomain: + addedAt: type: string - description: |- - CustomDomain is the domain that the deployment will be available on. - The max length is set to 243 to allow for a subdomain when confirming the domain. - name: - maxLength: 30 - minLength: 3 + email: type: string - body.JobRead: - type: object - properties: - createdAt: + firstName: type: string - finishedAt: + gravatarUrl: type: string id: type: string - lastError: - type: string - lastRunAt: + joinedAt: type: string - runAfter: + lastName: type: string - status: + memberStatus: type: string - type: + teamRole: type: string - userId: + username: type: string - body.JobUpdate: type: object + body.TeamMemberCreate: properties: - status: + id: type: string - enum: - - pending - - running - - failed - - terminated - - finished - - completed - body.K8sStats: + teamRole: + description: default to MemberRoleAdmin right now + type: string + required: + - id type: object + body.TeamMemberUpdate: properties: - clusters: - type: array - items: - $ref: '#/components/schemas/body.ClusterStats' - podCount: - type: integer - body.NotificationRead: + id: + type: string + teamRole: + description: default to MemberRoleAdmin right now + type: string + required: + - id type: object + body.TeamRead: properties: - completedAt: - type: string - content: - type: object - additionalProperties: true createdAt: type: string - id: + description: type: string - readAt: + id: type: string - toastedAt: + members: + items: + $ref: '#/components/schemas/body.TeamMember' + type: array + uniqueItems: false + name: type: string - type: + ownerId: type: string - userId: + resources: + items: + $ref: '#/components/schemas/body.TeamResource' + type: array + uniqueItems: false + updatedAt: type: string - body.NotificationUpdate: type: object + body.TeamResource: properties: - read: - type: boolean - toasted: - type: boolean - body.PortCreate: - required: - - name - - port - - protocol + id: + type: string + name: + type: string + type: + type: string type: object + body.TeamUpdate: properties: - httpProxy: - $ref: '#/components/schemas/body.HttpProxyCreate' + description: + maxLength: 1000 + type: string + members: + items: + $ref: '#/components/schemas/body.TeamMemberUpdate' + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false name: maxLength: 100 minLength: 1 type: string - port: - maximum: 65535 - minimum: 1 - type: integer - protocol: - type: string - enum: - - tcp - - udp - body.PortRead: + resources: + items: + type: string + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false type: object + body.TimestampedSystemCapacities: properties: - externalPort: - type: integer - httpProxy: - $ref: '#/components/schemas/body.HttpProxyRead' - name: - type: string - port: - type: integer - protocol: + capacities: + $ref: '#/components/schemas/body.SystemCapacities' + timestamp: type: string - body.PortUpdate: - required: - - name - - port - - protocol type: object + body.TimestampedSystemStats: properties: - httpProxy: - $ref: '#/components/schemas/body.HttpProxyUpdate' - name: - maxLength: 100 - minLength: 1 - type: string - port: - maximum: 65535 - minimum: 1 - type: integer - protocol: + stats: + $ref: '#/components/schemas/body.SystemStats' + timestamp: type: string - enum: - - tcp - - udp - body.PublicKey: - required: - - key - - name type: object + body.TimestampedSystemStatus: properties: - key: - type: string - name: - maxLength: 30 - minLength: 1 + status: + $ref: '#/components/schemas/body.SystemStatus' + timestamp: type: string - body.Quota: type: object + body.Usage: properties: cpuCores: type: number diskSize: - type: number - gpuLeaseDuration: - type: number - description: in hours - ram: - type: number - snapshots: - type: integer - body.RamCapacities: - type: object - properties: - total: type: integer - body.RamStatus: - type: object - properties: - load: - $ref: '#/components/schemas/body.RamStatusLoad' - body.RamStatusLoad: - type: object - properties: - main: + ram: type: number - body.ReplicaStatus: - type: object - properties: - availableReplicas: - type: integer - description: AvailableReplicas is the number of replicas that are available. - desiredReplicas: - type: integer - description: DesiredReplicas is the number of replicas that the deployment - should have. - readyReplicas: - type: integer - description: ReadyReplicas is the number of replicas that are ready. - unavailableReplicas: - type: integer - description: UnavailableReplicas is the number of replicas that are unavailable. - body.ResourceMigrationCreate: - required: - - resourceId - - type type: object + body.UserData: properties: - resourceId: - type: string - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - status: + key: + maxLength: 255 + minLength: 1 type: string - description: |- - Status is the status of the resource migration. - It is used by privileged admins to directly accept or reject a migration. - The field is ignored by non-admins. - - Possible values: - - accepted - - pending - type: + value: + maxLength: 255 + minLength: 1 type: string - description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - enum: - - updateOwner - updateOwner: - required: - - ownerId - type: object - properties: - ownerId: - type: string - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is ignored if the migration type is not updateOwner. - body.ResourceMigrationCreated: + required: + - key + - value type: object + body.UserRead: properties: - createdAt: - type: string - deletedAt: + admin: + type: boolean + apiKeys: + items: + $ref: '#/components/schemas/body.ApiKey' + type: array + uniqueItems: false + email: type: string - id: + firstName: type: string - jobId: + gravatarUrl: type: string - description: |- - JobID is the ID of the job that was created for the resource migration. - It will only be set if the migration was created with status 'accepted'. - resourceId: + id: type: string - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - resourceType: + lastName: type: string - description: |- - ResourceType is the type of the resource that is being migrated. - - Possible values: - - vm - - deployment - status: + publicKeys: + items: + $ref: '#/components/schemas/body.PublicKey' + type: array + uniqueItems: false + quota: + $ref: '#/components/schemas/body.Quota' + role: + $ref: '#/components/schemas/body.Role' + storageUrl: type: string - description: |- - Status is the status of the resource migration. - When this field is set to 'accepted', the migration will take place and then automatically be deleted. - type: + usage: + $ref: '#/components/schemas/body.Usage' + userData: + items: + $ref: '#/components/schemas/body.UserData' + type: array + uniqueItems: false + username: type: string + type: object + body.UserUpdate: + properties: + apiKeys: description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - updateOwner: - type: object - properties: - ownerId: - type: string - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is empty if the migration type is not updateOwner. - userId: - type: string - description: UserID is the ID of the user who initiated the migration. - body.ResourceMigrationRead: + ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted. + However, API keys cannot be created, use /apiKeys endpoint to create new API keys. + items: + $ref: '#/components/schemas/body.ApiKey' + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false + publicKeys: + items: + $ref: '#/components/schemas/body.PublicKey' + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false + userData: + items: + $ref: '#/components/schemas/body.UserData' + maxItems: 100 + minItems: 0 + type: array + uniqueItems: false type: object + body.VmActionCreate: properties: - createdAt: - type: string - deletedAt: + action: + enum: + - start + - stop + - restart + - repair type: string + required: + - action + type: object + body.VmActionCreated: + properties: id: type: string - resourceId: - type: string - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - resourceType: + jobId: type: string - description: |- - ResourceType is the type of the resource that is being migrated. - - Possible values: - - vm - - deployment - status: + type: object + body.VmCreate: + properties: + cpuCores: + minimum: 1 + type: integer + diskSize: + minimum: 10 + type: integer + name: + maxLength: 30 + minLength: 3 type: string - description: |- - Status is the status of the resource migration. - When this field is set to 'accepted', the migration will take place and then automatically be deleted. - type: + ports: + items: + $ref: '#/components/schemas/body.PortCreate' + maxItems: 10 + minItems: 0 + type: array + uniqueItems: false + ram: + minimum: 1 + type: integer + sshPublicKey: type: string - description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - updateOwner: - type: object - properties: - ownerId: - type: string - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is empty if the migration type is not updateOwner. - userId: + zone: type: string - description: UserID is the ID of the user who initiated the migration. - body.ResourceMigrationUpdate: required: - - status + - cpuCores + - diskSize + - name + - ram + - sshPublicKey type: object + body.VmCreated: properties: - code: + id: type: string - description: |- - Code is a token required when accepting a migration if the acceptor is not an admin. - It is sent to the acceptor using the notification API - status: + jobId: type: string - description: |- - Status is the status of the resource migration. - It is used to accept a migration by setting the status to 'accepted'. - If the acceptor is not an admin, a Code must be provided. - - Possible values: - - accepted - - pending - body.ResourceMigrationUpdated: type: object + body.VmDeleted: properties: - createdAt: - type: string - deletedAt: - type: string id: type: string jobId: type: string + type: object + body.VmGpuLease: + properties: + activatedAt: description: |- - JobID is the ID of the job that was created for the resource migration. - It will only be set if the migration was updated with status 'accepted'. - resourceId: + ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU + or 1 day after the lease was created if the user did not attach the GPU. type: string - description: |- - ResourceID is the ID of the resource that is being migrated. - This can be a VM ID, deployment ID, etc. depending on the type of the migration. - resourceType: + assignedAt: + description: AssignedAt specifies the time when the lease was assigned to + the user. type: string - description: |- - ResourceType is the type of the resource that is being migrated. - - Possible values: - - vm - - deployment - status: + createdAt: type: string + expiredAt: description: |- - Status is the status of the resource migration. - When this field is set to 'accepted', the migration will take place and then automatically be deleted. - type: + ExpiredAt specifies the time when the lease expired. + This is only present if the lease is expired. type: string + expiresAt: description: |- - Type is the type of the resource migration. - - Possible values: - - updateOwner - updateOwner: - type: object - properties: - ownerId: - type: string - description: |- - UpdateOwner is the set of parameters that are required for the updateOwner migration type. - It is empty if the migration type is not updateOwner. - userId: + ExpiresAt specifies the time when the lease will expire. + This is only present if the lease is active. type: string - description: UserID is the ID of the user who initiated the migration. - body.Role: + gpuGroupId: + type: string + id: + type: string + leaseDuration: + type: number type: object + body.VmRead: properties: - description: + accessedAt: + type: string + createdAt: + type: string + gpu: + $ref: '#/components/schemas/body.VmGpuLease' + host: + type: string + id: + type: string + internalName: type: string name: type: string - permissions: + ownerId: + type: string + ports: + items: + $ref: '#/components/schemas/body.PortRead' type: array + uniqueItems: false + repairedAt: + type: string + specs: + $ref: '#/components/schemas/body.VmSpecs' + sshConnectionString: + type: string + sshPublicKey: + type: string + status: + type: string + teams: items: type: string - quota: - $ref: '#/components/schemas/body.Quota' - body.SmDeleted: + type: array + uniqueItems: false + updatedAt: + type: string + zone: + type: string type: object + body.VmSnapshotCreated: properties: id: type: string jobId: type: string - body.SmRead: type: object + body.VmSnapshotDeleted: properties: - createdAt: - type: string id: type: string - ownerId: + jobId: type: string - url: + type: object + body.VmSnapshotRead: + properties: + created: type: string - zone: + id: + type: string + name: + type: string + status: type: string - body.SystemCapacities: type: object + body.VmSpecs: properties: - clusters: - type: array - description: Per Cluster - items: - $ref: '#/components/schemas/body.ClusterCapacities' - cpuCore: - type: object - description: Total - allOf: - - $ref: '#/components/schemas/body.CpuCoreCapacities' - gpu: - $ref: '#/components/schemas/body.GpuCapacities' - hosts: - type: array - description: Per Host - items: - $ref: '#/components/schemas/body.HostCapacities' + cpuCores: + type: integer + diskSize: + type: integer ram: - $ref: '#/components/schemas/body.RamCapacities' - body.SystemStats: + type: integer type: object + body.VmUpdate: properties: - k8s: - $ref: '#/components/schemas/body.K8sStats' - body.SystemStatus: + cpuCores: + minimum: 1 + type: integer + name: + maxLength: 30 + minLength: 3 + type: string + ports: + items: + $ref: '#/components/schemas/body.PortUpdate' + maxItems: 10 + minItems: 0 + type: array + uniqueItems: false + ram: + minimum: 1 + type: integer type: object + body.VmUpdated: properties: - hosts: - type: array - items: - $ref: '#/components/schemas/body.HostStatus' - body.TeamCreate: - required: - - name + id: + type: string + jobId: + type: string type: object + body.Volume: properties: - description: - maxLength: 1000 + appPath: + maxLength: 255 + minLength: 1 type: string - members: - maxItems: 100 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.TeamMemberCreate' name: - maxLength: 100 + maxLength: 30 + minLength: 3 + type: string + serverPath: + maxLength: 255 minLength: 1 type: string - resources: - maxItems: 100 - minItems: 0 - type: array - items: - type: string - body.TeamMember: + required: + - appPath + - name + - serverPath type: object + body.WorkerStatusRead: properties: - addedAt: - type: string - email: + name: type: string - firstName: + reportedAt: type: string - gravatarUrl: + status: type: string - id: + type: object + body.ZoneEndpoints: + properties: + deployment: type: string - joinedAt: + storage: type: string - lastName: + vm: type: string - memberStatus: + vmApp: type: string - teamRole: + type: object + body.ZoneRead: + properties: + capabilities: + items: + type: string + type: array + uniqueItems: false + description: type: string - username: + enabled: + type: boolean + endpoints: + $ref: '#/components/schemas/body.ZoneEndpoints' + legacy: + type: boolean + name: type: string - body.TeamMemberCreate: - required: - - id type: object + sys.Error: properties: - id: + code: type: string - teamRole: + msg: type: string - description: default to MemberRoleAdmin right now - body.TeamMemberUpdate: - required: - - id type: object + sys.ErrorResponse: properties: - id: + errors: + items: + $ref: '#/components/schemas/sys.Error' + type: array + uniqueItems: false + type: object + securitySchemes: + ApiKeyAuth: + flows: + authorizationCode: + authorizationUrl: https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth + tokenUrl: https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token + in: header + type: oauth2 +externalDocs: + description: "" + url: "" +info: + contact: + name: Support + url: https://github.com/kthcloud/go-deploy + description: This is the API explorer for the go-deploy API. You can use it as a + reference for the API endpoints. + license: + name: MIT License + url: https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme + termsOfService: http://swagger.io/terms/ + title: go-deploy API + version: "1.0" +openapi: 3.1.0 +paths: + /v2/deployments: + get: + description: List deployments + parameters: + - description: List all + in: query + name: all + schema: + type: boolean + - description: Filter by user ID + in: query + name: userId + schema: type: string - teamRole: + - description: Include shared + in: query + name: shared + schema: + type: boolean + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.DeploymentRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List deployments + tags: + - Deployment + post: + description: Create deployment + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentCreate' + description: Deployment body + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Create deployment + tags: + - Deployment + /v2/deployments/{deploymentId}: + delete: + description: Delete deployment + parameters: + - description: Deployment ID + in: path + name: deploymentId + required: true + schema: type: string - description: default to MemberRoleAdmin right now - body.TeamRead: - type: object - properties: - createdAt: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentCreated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete deployment + tags: + - Deployment + get: + description: Get deployment + parameters: + - description: Deployment ID + in: path + name: deploymentId + required: true + schema: type: string - description: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get deployment + tags: + - Deployment + post: + description: Update deployment + parameters: + - description: Deployment ID + in: path + name: deploymentId + required: true + schema: type: string - id: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentUpdate' + description: Deployment update + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentUpdated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update deployment + tags: + - Deployment + /v2/deployments/{deploymentId}/ciConfig: + get: + description: Get CI config + parameters: + - description: Deployment ID + in: path + name: deploymentId + required: true + schema: type: string - members: - type: array - items: - $ref: '#/components/schemas/body.TeamMember' - name: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.CiConfig' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get CI config + tags: + - Deployment + /v2/deployments/{deploymentId}/command: + post: + description: Do command + parameters: + - description: Deployment ID + in: path + name: deploymentId + required: true + schema: type: string - ownerId: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.DeploymentCommand' + description: Command body + required: true + responses: + "204": + description: No Content + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "423": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Locked + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Do command + tags: + - Deployment + /v2/deployments/{deploymentId}/logs: + get: + description: Get logs using Server-Sent Events + parameters: + - description: Deployment ID + in: path + name: deploymentId + required: true + schema: type: string - resources: - type: array - items: - $ref: '#/components/schemas/body.TeamResource' - updatedAt: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + type: string + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get logs using Server-Sent Events + tags: + - Deployment + /v2/discover: + get: + description: Discover + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.DiscoverRead' + description: OK + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: Discover + tags: + - Discover + /v2/gpuGroups: + get: + description: List GPU groups + parameters: + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.GpuGroupRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "423": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Locked + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List GPU groups + tags: + - GpuGroup + /v2/gpuGroups/{gpuGroupId}: + get: + description: Get GPU group + parameters: + - description: GPU group ID + in: path + name: gpuGroupId + required: true + schema: type: string - body.TeamResource: - type: object - properties: - id: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuGroupRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "423": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Locked + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get GPU group + tags: + - GpuGroup + /v2/gpuLeases: + get: + description: List GPU leases + parameters: + - description: List all + in: query + name: all + schema: + type: boolean + - description: Filter by VM ID + in: query + name: vmId + schema: type: string - name: + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.GpuLeaseRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "423": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Locked + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List GPU leases + tags: + - GpuLease + post: + description: Create GPU lease + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseCreate' + description: GPU lease + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseCreated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Create GPU Lease + tags: + - GpuLease + /v2/gpuLeases/{gpuLeaseId}: + delete: + description: Delete GPU lease + parameters: + - description: GPU lease ID + in: path + name: gpuLeaseId + required: true + schema: type: string - type: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseDeleted' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete GPU lease + tags: + - GpuLease + get: + description: Get GPU lease + parameters: + - description: GPU lease ID + in: path + name: gpuLeaseId + required: true + schema: type: string - body.TeamUpdate: - type: object - properties: - description: - maxLength: 1000 + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "423": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Locked + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get GPU lease + tags: + - GpuLease + post: + description: Update GPU lease + parameters: + - description: GPU lease ID + in: path + name: gpuLeaseId + required: true + schema: type: string - members: - maxItems: 100 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.TeamMemberUpdate' - name: - maxLength: 100 - minLength: 1 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseUpdate' + description: GPU lease + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.GpuLeaseUpdated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update GPU lease + tags: + - GpuLease + /v2/hooks/harbor: + post: + description: Handle Harbor hook + parameters: + - description: Basic auth token + in: header + name: Authorization + schema: type: string - resources: - maxItems: 100 - minItems: 0 - type: array - items: - type: string - body.TimestampedSystemCapacities: - type: object - properties: - capacities: - $ref: '#/components/schemas/body.SystemCapacities' - timestamp: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.HarborWebhook' + description: Harbor webhook body + required: true + responses: + "204": + description: No Content + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: Handle Harbor hook + tags: + - Deployment + /v2/hosts: + get: + description: List Hosts + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.HostRead' + type: array + description: OK + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: List Hosts + tags: + - Host + /v2/jobs: + get: + description: List jobs + parameters: + - description: List all + in: query + name: all + schema: + type: boolean + - description: Filter by user ID + in: query + name: userId + schema: type: string - body.TimestampedSystemStats: - type: object - properties: - stats: - $ref: '#/components/schemas/body.SystemStats' - timestamp: + - description: Filter by type + in: query + name: type + schema: type: string - body.TimestampedSystemStatus: - type: object - properties: - status: - $ref: '#/components/schemas/body.SystemStatus' - timestamp: + - description: Filter by status + in: query + name: status + schema: type: string - body.Usage: - type: object - properties: - cpuCores: - type: number - diskSize: + - description: Page number + in: query + name: page + schema: type: integer - ram: - type: number - body.UserData: - required: - - key - - value - type: object - properties: - key: - maxLength: 255 - minLength: 1 + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.JobRead' + type: array + description: OK + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List jobs + tags: + - Job + /v2/jobs/{jobId}: + get: + description: GetJob job by id + parameters: + - description: Job ID + in: path + name: jobId + required: true + schema: type: string - value: - maxLength: 255 - minLength: 1 + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.JobRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: GetJob job by id + tags: + - Job + post: + description: Update job. Only allowed for admins. + parameters: + - description: Job ID + in: path + name: jobId + required: true + schema: type: string - body.UserRead: - type: object - properties: - admin: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.JobUpdate' + description: Job update + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.JobRead' + description: OK + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update job + tags: + - Job + /v2/metrics: + get: + description: Get metrics + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + type: string + description: OK + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: Get metrics + tags: + - Metrics + /v2/notifications: + get: + description: List notifications + parameters: + - description: List all notifications + in: query + name: all + schema: type: boolean - apiKeys: - type: array - items: - $ref: '#/components/schemas/body.ApiKey' - email: + - description: Filter by user ID + in: query + name: userId + schema: type: string - firstName: + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.NotificationRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List notifications + tags: + - Notification + /v2/notifications/{notificationId}: + delete: + description: Delete notification + parameters: + - description: Notification ID + in: path + name: notificationId + required: true + schema: type: string - gravatarUrl: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + type: object + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete notification + tags: + - Notification + get: + description: Get notification + parameters: + - description: Notification ID + in: path + name: notificationId + required: true + schema: type: string - id: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.NotificationRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get notification + tags: + - Notification + post: + description: Update notification + parameters: + - description: Notification ID + in: path + name: notificationId + required: true + schema: type: string - lastName: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.NotificationUpdate' + description: Notification update + required: true + responses: + "200": + content: + application/json: + schema: + type: object + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update notification + tags: + - Notification + /v2/register: + get: + description: Register resource + requestBody: + content: + application/json: + schema: + type: object + responses: + "204": + description: No Content + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: Register resource + tags: + - Register + /v2/resourceMigrations: + get: + description: List resource migrations + parameters: + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.ResourceMigrationRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List resource migrations + tags: + - ResourceMigration + post: + description: Create resource migration + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationCreate' + description: Resource Migration Create + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationCreated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Create resource migration + tags: + - ResourceMigration + /v2/resourceMigrations/{resourceMigrationId}: + delete: + description: Delete resource migration + parameters: + - description: Resource Migration ID + in: path + name: resourceMigrationId + required: true + schema: type: string - publicKeys: - type: array - items: - $ref: '#/components/schemas/body.PublicKey' - quota: - $ref: '#/components/schemas/body.Quota' - role: - $ref: '#/components/schemas/body.Role' - storageUrl: + requestBody: + content: + application/json: + schema: + type: object + responses: + "204": + description: No Content + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete resource migration + tags: + - ResourceMigration + get: + description: Get resource migration + parameters: + - description: Resource Migration ID + in: path + name: resourceMigrationId + required: true + schema: type: string - usage: - $ref: '#/components/schemas/body.Usage' - userData: - type: array - items: - $ref: '#/components/schemas/body.UserData' - username: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get resource migration + tags: + - ResourceMigration + post: + description: Update resource migration + parameters: + - description: Resource Migration ID + in: path + name: resourceMigrationId + required: true + schema: type: string - body.UserUpdate: - type: object - properties: - apiKeys: - maxItems: 100 - minItems: 0 - type: array - description: |- - ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted. - However, API keys cannot be created, use /apiKeys endpoint to create new API keys. - items: - $ref: '#/components/schemas/body.ApiKey' - publicKeys: - maxItems: 100 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.PublicKey' - userData: - maxItems: 100 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.UserData' - body.VmActionCreate: - required: - - action - type: object - properties: - action: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationUpdate' + description: Resource Migration Update + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.ResourceMigrationUpdated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update resource migration + tags: + - ResourceMigration + /v2/snapshots: + get: + description: List snapshots + parameters: + - description: Filter by VM ID + in: path + name: vmId + required: true + schema: type: string - enum: - - start - - stop - - restart - - repair - body.VmActionCreated: - type: object - properties: - id: + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.VmSnapshotRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "423": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Locked + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List snapshots + tags: + - Snapshot + post: + description: Create snapshot + parameters: + - description: VM ID + in: path + name: vmId + required: true + schema: type: string - jobId: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmSnapshotCreated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Create snapshot + tags: + - Snapshot + /v2/storageManagers: + get: + description: Get storage manager list + parameters: + - description: List all + in: query + name: all + schema: + type: boolean + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.SmRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get storage manager list + tags: + - StorageManager + /v2/storageManagers/{storageManagerId}: + get: + description: Delete storage manager + parameters: + - description: Storage manager ID + in: path + name: storageManagerId + required: true + schema: type: string - body.VmCreate: - required: - - cpuCores - - diskSize - - name - - ram - - sshPublicKey - type: object - properties: - cpuCores: - minimum: 1 + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.SmDeleted' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete storage manager + tags: + - StorageManager + /v2/systemCapacities: + get: + description: List system capacities + parameters: + - description: "n" + in: query + name: "n" + schema: type: integer - diskSize: - minimum: 10 + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.TimestampedSystemCapacities' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: List system capacities + tags: + - System + /v2/systemStats: + get: + description: List system stats + parameters: + - description: "n" + in: query + name: "n" + schema: type: integer - name: - maxLength: 30 - minLength: 3 + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.TimestampedSystemStats' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: List system stats + tags: + - System + /v2/systemStatus: + get: + description: List system stats + parameters: + - description: "n" + in: query + name: "n" + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.TimestampedSystemStatus' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: List system stats + tags: + - System + /v2/teams: + get: + description: List teams + parameters: + - description: List all + in: query + name: all + schema: + type: boolean + - description: Filter by user ID + in: query + name: userId + schema: type: string - ports: - maxItems: 10 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.PortCreate' - ram: - minimum: 1 + - description: Page number + in: query + name: page + schema: type: integer - sshPublicKey: - type: string - zone: - type: string - body.VmCreated: - type: object - properties: - id: - type: string - jobId: - type: string - body.VmDeleted: - type: object - properties: - id: - type: string - jobId: - type: string - body.VmGpuLease: - type: object - properties: - activatedAt: - type: string - description: |- - ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU - or 1 day after the lease was created if the user did not attach the GPU. - assignedAt: - type: string - description: AssignedAt specifies the time when the lease was assigned to - the user. - createdAt: - type: string - expiredAt: - type: string - description: |- - ExpiredAt specifies the time when the lease expired. - This is only present if the lease is expired. - expiresAt: - type: string - description: |- - ExpiresAt specifies the time when the lease will expire. - This is only present if the lease is active. - gpuGroupId: - type: string - id: - type: string - leaseDuration: - type: number - body.VmRead: - type: object - properties: - accessedAt: - type: string - createdAt: - type: string - gpu: - $ref: '#/components/schemas/body.VmGpuLease' - host: - type: string - id: - type: string - internalName: - type: string - name: - type: string - ownerId: - type: string - ports: - type: array - items: - $ref: '#/components/schemas/body.PortRead' - repairedAt: - type: string - specs: - $ref: '#/components/schemas/body.VmSpecs' - sshConnectionString: - type: string - sshPublicKey: - type: string - status: - type: string - teams: - type: array - items: - type: string - updatedAt: - type: string - zone: + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.TeamRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List teams + tags: + - Team + post: + description: Create team + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamCreate' + description: Team + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Create team + tags: + - Team + /v2/teams/{teamId}: + delete: + description: Delete team + parameters: + - description: Team ID + in: path + name: teamId + required: true + schema: type: string - body.VmSnapshotCreated: - type: object - properties: - id: + requestBody: + content: + application/json: + schema: + type: object + responses: + "204": + description: No Content + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete team + tags: + - Team + get: + description: Get team + parameters: + - description: Team ID + in: path + name: teamId + required: true + schema: type: string - jobId: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get team + tags: + - Team + post: + description: Update team + parameters: + - description: Team ID + in: path + name: teamId + required: true + schema: type: string - body.VmSnapshotDeleted: - type: object - properties: - id: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamUpdate' + description: Team + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.TeamRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/body.BindingError' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update team + tags: + - Team + /v2/users: + get: + description: List users + parameters: + - description: List all + in: query + name: all + schema: + type: boolean + - description: Discovery mode + in: query + name: discover + schema: + type: boolean + - description: Search query + in: query + name: search + schema: type: string - jobId: + - description: Page number + in: query + name: page + schema: + type: integer + - description: Number of items per page + in: query + name: pageSize + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.UserRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List users + tags: + - User + /v2/users/{userId}: + get: + description: Get user + parameters: + - description: User ID + in: path + name: userId + required: true + schema: type: string - body.VmSnapshotRead: - type: object - properties: - created: + - description: Discovery mode + in: query + name: discover + schema: + type: boolean + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.UserRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get user + tags: + - User + post: + description: Update user + parameters: + - description: User ID + in: path + name: userId + required: true + schema: type: string - id: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.UserUpdate' + description: User update + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.UserRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update user + tags: + - User + /v2/users/{userId}/apiKeys: + post: + description: Create API key + parameters: + - description: User ID + in: path + name: userId + required: true + schema: type: string - name: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.ApiKeyCreate' + description: API key create body + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.ApiKeyCreated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Create API key + tags: + - User + /v2/vmActions: + post: + description: Creates a new action + parameters: + - description: VM ID + in: path + name: vmId + required: true + schema: type: string - status: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmActionCreate' + description: actions body + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmActionCreated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Creates a new action + tags: + - VmAction + /v2/vms: + get: + description: List VMs + parameters: + - description: List all + in: query + name: all + schema: + type: boolean + - description: Filter by user ID + in: query + name: userId + schema: type: string - body.VmSpecs: - type: object - properties: - cpuCores: - type: integer - diskSize: - type: integer - ram: - type: integer - body.VmUpdate: - type: object - properties: - cpuCores: - minimum: 1 + - description: Page number + in: query + name: page + schema: type: integer - name: - maxLength: 30 - minLength: 3 - type: string - ports: - maxItems: 10 - minItems: 0 - type: array - items: - $ref: '#/components/schemas/body.PortUpdate' - ram: - minimum: 1 + - description: Number of items per page + in: query + name: pageSize + schema: type: integer - body.VmUpdated: - type: object - properties: - id: - type: string - jobId: - type: string - body.Volume: - required: - - appPath - - name - - serverPath - type: object - properties: - appPath: - maxLength: 255 - minLength: 1 - type: string - name: - maxLength: 30 - minLength: 3 - type: string - serverPath: - maxLength: 255 - minLength: 1 - type: string - body.WorkerStatusRead: - type: object - properties: - name: - type: string - reportedAt: - type: string - status: - type: string - body.ZoneEndpoints: - type: object - properties: - deployment: - type: string - storage: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.VmRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List VMs + tags: + - VM + post: + description: Create VM + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmCreate' + description: VM body + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmCreated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Create VM + tags: + - VM + /v2/vms/{vmId}: + delete: + description: Delete VM + parameters: + - description: VM ID + in: path + name: vmId + required: true + schema: type: string - vm: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmDeleted' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete VM + tags: + - VM + get: + description: Get VM + parameters: + - description: VM ID + in: path + name: vmId + required: true + schema: type: string - vmApp: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get VM + tags: + - VM + post: + description: Update VM + parameters: + - description: VM ID + in: path + name: vmId + required: true + schema: type: string - body.ZoneRead: - type: object - properties: - capabilities: - type: array - items: - type: string - description: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmUpdate' + description: VM update + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmUpdated' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Update VM + tags: + - VM + /v2/vms/{vmId}/snapshot/{snapshotId}: + delete: + description: Delete snapshot + parameters: + - description: VM ID + in: path + name: vmId + required: true + schema: type: string - enabled: - type: boolean - endpoints: - $ref: '#/components/schemas/body.ZoneEndpoints' - legacy: - type: boolean - name: + - description: Snapshot ID + in: path + name: snapshotId + required: true + schema: type: string - sys.Error: - type: object - properties: - code: + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmSnapshotDeleted' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Delete snapshot + tags: + - Snapshot + post: + description: Get snapshot + parameters: + - description: VM ID + in: path + name: vmId + required: true + schema: type: string - msg: + - description: Snapshot ID + in: path + name: snapshotId + required: true + schema: type: string - sys.ErrorResponse: - type: object - properties: - errors: - type: array - items: - $ref: '#/components/schemas/sys.Error' - securitySchemes: - ApiKeyAuth: - type: apiKey - name: X-Api-Key - in: header - KeycloakOAuth: - type: oauth2 - flows: - authorizationCode: - authorizationUrl: https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth - tokenUrl: https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token - scopes: - email: email - openid: openid - profile: profile -x-original-swagger-version: "2.0" + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.VmSnapshotRead' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get snapshot + tags: + - Snapshot + /v2/workerStatus: + get: + description: List of worker status + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.WorkerStatusRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + summary: List worker status + tags: + - Status + /v2/zones: + get: + description: List zones + requestBody: + content: + application/json: + schema: + type: object + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.ZoneRead' + type: array + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List zones + tags: + - Zone diff --git a/docs/api/v2/handlers/serve_fs.go b/docs/api/v2/handlers/serve_fs.go new file mode 100644 index 00000000..da4a2b6e --- /dev/null +++ b/docs/api/v2/handlers/serve_fs.go @@ -0,0 +1,52 @@ +package handlers + +import ( + "fmt" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + "github.com/swaggo/swag/v2" + + swaggerfiles "github.com/swaggo/files/v2" +) + +func ServeDocs(basePath string) func(ctx *gin.Context) { + return func(ctx *gin.Context) { + filePath := ctx.Param("any") + + if strings.TrimPrefix(filePath, "/") == "swagger-initializer.js" { + customScript := fmt.Sprintf(`window.onload = function() { + window.ui = SwaggerUIBundle({ + url: "%s/doc.json", + dom_id: '#swagger-ui', + deepLinking: true, + presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIStandalonePreset + ], + plugins: [ + SwaggerUIBundle.plugins.DownloadUrl + ], + layout: "StandaloneLayout" + }); +};`, basePath) + ctx.Data(http.StatusOK, "application/javascript", []byte(customScript)) + return + } + + // Serve the Swagger documentation + if strings.TrimPrefix(filePath, "/") == "doc.json" { + doc, err := swag.ReadDoc("V2") + if err != nil { + ctx.String(http.StatusInternalServerError, "Failed to load documentation") + return + } + ctx.Data(http.StatusOK, "application/json", []byte(doc)) + return + } + + ctx.Request.URL.Path = filePath + http.FileServer(http.FS(swaggerfiles.FS)).ServeHTTP(ctx.Writer, ctx.Request) + } +} diff --git a/go.mod b/go.mod index d7bf6c1a..b241cbfe 100644 --- a/go.mod +++ b/go.mod @@ -25,12 +25,11 @@ require ( github.com/rancher/go-rancher v0.1.0 github.com/redis/go-redis/v9 v9.6.1 github.com/stretchr/testify v1.9.0 - github.com/swaggo/files v1.0.1 - github.com/swaggo/gin-swagger v1.6.0 - github.com/swaggo/swag v1.16.3 - go.mongodb.org/mongo-driver v1.16.0 + github.com/swaggo/files/v2 v2.0.2 + github.com/swaggo/swag/v2 v2.0.0-rc4 + go.mongodb.org/mongo-driver v1.17.2 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.25.0 + golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 golang.org/x/oauth2 v0.21.0 @@ -102,6 +101,7 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/sv-tools/openapi v0.2.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect @@ -113,10 +113,10 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/go.sum b/go.sum index 4832d0a1..7eaa0603 100644 --- a/go.sum +++ b/go.sum @@ -109,8 +109,6 @@ github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSy github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= -github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= -github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/zap v1.1.3 h1:9e/U9fYd4/OBfmSEBs5hHZq114uACn7bpuzvCkcJySA= @@ -439,12 +437,12 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= -github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= -github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= -github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= -github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= -github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= +github.com/sv-tools/openapi v0.2.1 h1:ES1tMQMJFGibWndMagvdoo34T1Vllxr1Nlm5wz6b1aA= +github.com/sv-tools/openapi v0.2.1/go.mod h1:k5VuZamTw1HuiS9p2Wl5YIDWzYnHG6/FgPOSFXLAhGg= +github.com/swaggo/files/v2 v2.0.2 h1:Bq4tgS/yxLB/3nwOMcul5oLEUKa877Ykgz3CJMVbQKU= +github.com/swaggo/files/v2 v2.0.2/go.mod h1:TVqetIzZsO9OhHX1Am9sRf9LdrFZqoK49N37KON/jr0= +github.com/swaggo/swag/v2 v2.0.0-rc4 h1:SZ8cK68gcV6cslwrJMIOqPkJELRwq4gmjvk77MrvHvY= +github.com/swaggo/swag/v2 v2.0.0-rc4/go.mod h1:Ow7Y8gF16BTCDn8YxZbyKn8FkMLRUHekv1kROJZpbvE= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -467,8 +465,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.16.0 h1:tpRsfBJMROVHKpdGyc1BBEzzjDUWjItxbVSZ8Ls4BQ4= -go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw= +go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= +go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -500,8 +498,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -583,7 +581,6 @@ golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -606,8 +603,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -667,14 +664,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -684,9 +680,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/main.go b/main.go index 24a43088..b65b7676 100644 --- a/main.go +++ b/main.go @@ -17,12 +17,15 @@ import ( // @SecurityDefinitions.apikey ApiKeyAuth // @In header // @Name X-Api-Key + // @SecurityDefinitions.oauth2.accessCode KeycloakOAuth // @authorizationUrl https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth // @tokenUrl https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token // @scope.openid openid // @scope.profile profile // @scope.email email +// @In header +// @Name Authorization func main() { options := cmd.ParseFlags() diff --git a/routers/router.go b/routers/router.go index 86265649..d57fc673 100644 --- a/routers/router.go +++ b/routers/router.go @@ -1,14 +1,18 @@ package routers import ( + "net/http" + "net/url" + "reflect" + "strings" + "time" + ginzap "github.com/gin-contrib/zap" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" - "github.com/penglongli/gin-metrics/ginmetrics" - swaggerfiles "github.com/swaggo/files" - ginSwagger "github.com/swaggo/gin-swagger" docsV2 "github.com/kthcloud/go-deploy/docs/api/v2" + docsV2Handlers "github.com/kthcloud/go-deploy/docs/api/v2/handlers" "github.com/kthcloud/go-deploy/models/mode" "github.com/kthcloud/go-deploy/pkg/auth" "github.com/kthcloud/go-deploy/pkg/config" @@ -18,11 +22,7 @@ import ( "github.com/kthcloud/go-deploy/routers/api/v2/middleware" "github.com/kthcloud/go-deploy/routers/api/validators" "github.com/kthcloud/go-deploy/routers/routes" - "net/http" - "net/url" - "reflect" - "strings" - "time" + "github.com/penglongli/gin-metrics/ginmetrics" ) // NewRouter creates a new router @@ -67,8 +67,11 @@ func NewRouter() *gin.Engine { //// Swagger routes // v2 docsV2.SwaggerInfoV2.BasePath = basePath - public.GET("/v2/docs/*any", ginSwagger.WrapHandler(swaggerfiles.Handler, ginSwagger.InstanceName("V2"))) + docsV2.SwaggerInfoV2.Host = "" + docsV2.SwaggerInfoV2.Schemes = []string{"http", "https"} + //public.GET("/v2/docs/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) + public.GET("/v2/docs/*any", docsV2Handlers.ServeDocs(basePath+"/v2/docs")) //// Health check routes public.Any("/healthz", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status": "ok"}) diff --git a/scripts/convert-to-v3-docs.sh b/scripts/convert-to-v3-docs.sh deleted file mode 100755 index 3ed68c50..00000000 --- a/scripts/convert-to-v3-docs.sh +++ /dev/null @@ -1,29 +0,0 @@ -# This is currently needed since Gin swagger does not support OpenAPI 3.* yet - -# Convert the Swagger output (2.0) to OpenAPI 3.0 using [POST] https://converter.swagger.io/api/convert -# Payload is the entire content of the swagger.json file -# The output is saved to the same file - -function convert_to_v3() { - local base_filepath=$1 - # shellcheck disable=SC2155 - local payload=$(cat "$base_filepath.yaml") - # shellcheck disable=SC2155 - local v3_res_yaml=$(curl -X POST 'https://converter.swagger.io/api/convert' \ - -H "accept: application/yaml" \ - -H "content-type: application/yaml" \ - --data-raw "$payload") - # shellcheck disable=SC2155 - local v3_res_json=$(curl -X POST 'https://converter.swagger.io/api/convert' \ - -H "accept: application/json" \ - -H "content-type: application/yaml" \ - --data-raw "$payload") - - echo "$v3_res_yaml" >"$base_filepath.yaml" - echo "$v3_res_json" >"$base_filepath.json" -} - -convert_to_v3 '../docs/api/v2/V2_swagger' - - -echo "Converted to OpenAPI 3.0" \ No newline at end of file diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh index 8911d758..907f1162 100755 --- a/scripts/generate-docs.sh +++ b/scripts/generate-docs.sh @@ -1,4 +1,4 @@ echo "Installing swaggo/swag" -go install github.com/swaggo/swag/cmd/swag@latest +go install github.com/swaggo/swag/v2/cmd/swag@latest -swag init --dir ../ -o ../docs/api/v2 --exclude ../routers/api/v1 --instanceName "V2" +swag init --dir ../ -o ../docs/api/v2 --exclude ../routers/api/v1 --instanceName "V2" -v3.1 From aa1ed7d7acc6d9e2d2736969e9d9fb261a5e688d Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 14:08:17 +0100 Subject: [PATCH 07/36] rm @accept json annotation on GET requests so they dont have a request body in the openapi spec --- docs/api/v2/V2_docs.go | 4 +- docs/api/v2/V2_swagger.json | 4490 +----------------------- docs/api/v2/V2_swagger.yaml | 134 +- routers/api/v2/deployment.go | 2 - routers/api/v2/deployment_ci_config.go | 1 - routers/api/v2/deployment_logs.go | 1 - routers/api/v2/discover.go | 1 - routers/api/v2/gpu_group.go | 2 - routers/api/v2/gpu_lease.go | 2 - routers/api/v2/hosts.go | 2 +- routers/api/v2/register.go | 2 +- routers/api/v2/resource_migration.go | 2 - routers/api/v2/sm.go | 3 - routers/api/v2/snapshot.go | 1 - routers/api/v2/system.go | 6 +- routers/api/v2/user.go | 2 - routers/api/v2/virtual_routes.go | 1 - routers/api/v2/vm.go | 2 - routers/api/v2/worker_status.go | 1 - routers/api/v2/zone.go | 1 - 20 files changed, 16 insertions(+), 4644 deletions(-) diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index bc009def..477a1c10 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -6,10 +6,10 @@ import "github.com/swaggo/swag/v2" const docTemplateV2 = `{ "schemes": {{ marshal .Schemes }}, - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"{{escape .Description}}","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"{{.Title}}","version":"{{.Version}}"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"get":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"get":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" }` diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index f64173c7..62181d53 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -1,4485 +1,7 @@ { - "components": { - "schemas": { - "body.ApiKey": { - "properties": { - "createdAt": { "type": "string" }, - "expiresAt": { "type": "string" }, - "name": { "type": "string" } - }, - "type": "object" - }, - "body.ApiKeyCreate": { - "properties": { - "expiresAt": { "type": "string" }, - "name": { "type": "string" } - }, - "required": ["expiresAt", "name"], - "type": "object" - }, - "body.ApiKeyCreated": { - "properties": { - "createdAt": { "type": "string" }, - "expiresAt": { "type": "string" }, - "key": { "type": "string" }, - "name": { "type": "string" } - }, - "type": "object" - }, - "body.BindingError": { - "properties": { - "validationErrors": { - "additionalProperties": { - "items": { "type": "string" }, - "type": "array" - }, - "type": "object" - } - }, - "type": "object" - }, - "body.CiConfig": { - "properties": { "config": { "type": "string" } }, - "type": "object" - }, - "body.ClusterCapacities": { - "properties": { - "cluster": { "type": "string" }, - "cpuCore": { "$ref": "#/components/schemas/body.CpuCoreCapacities" }, - "gpu": { "$ref": "#/components/schemas/body.GpuCapacities" }, - "ram": { "$ref": "#/components/schemas/body.RamCapacities" } - }, - "type": "object" - }, - "body.ClusterStats": { - "properties": { - "cluster": { "type": "string" }, - "podCount": { "type": "integer" } - }, - "type": "object" - }, - "body.CpuCoreCapacities": { - "description": "Total", - "properties": { "total": { "type": "integer" } }, - "type": "object" - }, - "body.CpuStatus": { - "properties": { - "load": { "$ref": "#/components/schemas/body.CpuStatusLoad" }, - "temp": { "$ref": "#/components/schemas/body.CpuStatusTemp" } - }, - "type": "object" - }, - "body.CpuStatusLoad": { - "properties": { - "cores": { - "items": { "type": "integer" }, - "type": "array", - "uniqueItems": false - }, - "main": { "type": "number" }, - "max": { "type": "number" } - }, - "type": "object" - }, - "body.CpuStatusTemp": { - "properties": { - "cores": { - "items": { "type": "integer" }, - "type": "array", - "uniqueItems": false - }, - "main": { "type": "number" }, - "max": { "type": "number" } - }, - "type": "object" - }, - "body.CustomDomainRead": { - "properties": { - "domain": { "type": "string" }, - "secret": { "type": "string" }, - "status": { "type": "string" }, - "url": { "type": "string" } - }, - "type": "object" - }, - "body.DeploymentCommand": { - "properties": { "command": { "enum": ["restart"], "type": "string" } }, - "required": ["command"], - "type": "object" - }, - "body.DeploymentCreate": { - "properties": { - "args": { - "items": { "type": "string" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "cpuCores": { "type": "number" }, - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "envs": { - "items": { "$ref": "#/components/schemas/body.Env" }, - "maxItems": 1000, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "healthCheckPath": { - "maxLength": 1000, - "minLength": 0, - "type": "string" - }, - "image": { "maxLength": 1000, "minLength": 1, "type": "string" }, - "initCommands": { - "items": { "type": "string" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "name": { "maxLength": 30, "minLength": 3, "type": "string" }, - "private": { - "description": "Deprecated: Use Visibility instead.", - "type": "boolean" - }, - "ram": { "type": "number" }, - "replicas": { "maximum": 100, "minimum": 0, "type": "integer" }, - "visibility": { - "enum": ["public", "private", "auth"], - "type": "string" - }, - "volumes": { - "items": { "$ref": "#/components/schemas/body.Volume" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "zone": { - "description": "Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.", - "type": "string" - } - }, - "required": ["name"], - "type": "object" - }, - "body.DeploymentCreated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.DeploymentRead": { - "properties": { - "accessedAt": { "type": "string" }, - "args": { - "items": { "type": "string" }, - "type": "array", - "uniqueItems": false - }, - "createdAt": { "type": "string" }, - "customDomain": { - "$ref": "#/components/schemas/body.CustomDomainRead" - }, - "envs": { - "items": { "$ref": "#/components/schemas/body.Env" }, - "type": "array", - "uniqueItems": false - }, - "error": { "type": "string" }, - "healthCheckPath": { "type": "string" }, - "id": { "type": "string" }, - "image": { "type": "string" }, - "initCommands": { - "items": { "type": "string" }, - "type": "array", - "uniqueItems": false - }, - "integrations": { - "description": "Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub", - "items": { "type": "string" }, - "type": "array", - "uniqueItems": false - }, - "internalPort": { "type": "integer" }, - "name": { "type": "string" }, - "ownerId": { "type": "string" }, - "pingResult": { "type": "integer" }, - "private": { - "description": "Deprecated: Use Visibility instead.", - "type": "boolean" - }, - "repairedAt": { "type": "string" }, - "replicaStatus": { - "$ref": "#/components/schemas/body.ReplicaStatus" - }, - "restartedAt": { "type": "string" }, - "specs": { "$ref": "#/components/schemas/body.DeploymentSpecs" }, - "status": { "type": "string" }, - "storageUrl": { "type": "string" }, - "teams": { - "items": { "type": "string" }, - "type": "array", - "uniqueItems": false - }, - "type": { "type": "string" }, - "updatedAt": { "type": "string" }, - "url": { "type": "string" }, - "visibility": { "type": "string" }, - "volumes": { - "items": { "$ref": "#/components/schemas/body.Volume" }, - "type": "array", - "uniqueItems": false - }, - "zone": { "type": "string" } - }, - "type": "object" - }, - "body.DeploymentSpecs": { - "properties": { - "cpuCores": { "type": "number" }, - "ram": { "type": "number" }, - "replicas": { "type": "integer" } - }, - "type": "object" - }, - "body.DeploymentUpdate": { - "properties": { - "args": { - "items": { "type": "string" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "cpuCores": { "type": "number" }, - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "envs": { - "items": { "$ref": "#/components/schemas/body.Env" }, - "maxItems": 1000, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "healthCheckPath": { - "maxLength": 1000, - "minLength": 0, - "type": "string" - }, - "image": { "maxLength": 1000, "minLength": 1, "type": "string" }, - "initCommands": { - "items": { "type": "string" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "name": { "maxLength": 30, "minLength": 3, "type": "string" }, - "private": { - "description": "Deprecated: Use Visibility instead.", - "type": "boolean" - }, - "ram": { "type": "number" }, - "replicas": { "maximum": 100, "minimum": 0, "type": "integer" }, - "visibility": { - "enum": ["public", "private", "auth"], - "type": "string" - }, - "volumes": { - "items": { "$ref": "#/components/schemas/body.Volume" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - } - }, - "required": ["name"], - "type": "object" - }, - "body.DeploymentUpdated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.DiscoverRead": { - "properties": { - "roles": { - "items": { "$ref": "#/components/schemas/body.Role" }, - "type": "array", - "uniqueItems": false - }, - "version": { "type": "string" } - }, - "type": "object" - }, - "body.Env": { - "properties": { - "name": { "maxLength": 100, "minLength": 1, "type": "string" }, - "value": { "maxLength": 10000, "minLength": 1, "type": "string" } - }, - "required": ["name", "value"], - "type": "object" - }, - "body.GpuCapacities": { - "properties": { "total": { "type": "integer" } }, - "type": "object" - }, - "body.GpuGroupRead": { - "properties": { - "available": { "type": "integer" }, - "displayName": { "type": "string" }, - "id": { "type": "string" }, - "name": { "type": "string" }, - "total": { "type": "integer" }, - "vendor": { "type": "string" }, - "zone": { "type": "string" } - }, - "type": "object" - }, - "body.GpuLeaseCreate": { - "properties": { - "gpuGroupId": { - "description": "GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.", - "type": "string" - }, - "leaseForever": { - "description": "LeaseForever is used to specify whether the lease should be created forever.", - "type": "boolean" - } - }, - "required": ["gpuGroupId"], - "type": "object" - }, - "body.GpuLeaseCreated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.GpuLeaseDeleted": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.GpuLeaseRead": { - "properties": { - "activatedAt": { - "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", - "type": "string" - }, - "active": { "type": "boolean" }, - "assignedAt": { - "description": "AssignedAt specifies the time when the lease was assigned to the user.", - "type": "string" - }, - "createdAt": { "type": "string" }, - "expiredAt": { "type": "string" }, - "expiresAt": { - "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", - "type": "string" - }, - "gpuGroupId": { "type": "string" }, - "id": { "type": "string" }, - "leaseDuration": { "type": "number" }, - "queuePosition": { "type": "integer" }, - "userId": { "type": "string" }, - "vmId": { - "description": "VmID is set when the lease is attached to a VM.", - "type": "string" - } - }, - "type": "object" - }, - "body.GpuLeaseUpdate": { - "properties": { - "vmId": { - "description": "VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.", - "type": "string" - } - }, - "type": "object" - }, - "body.GpuLeaseUpdated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.GpuStatus": { - "properties": { - "temp": { - "items": { "$ref": "#/components/schemas/body.GpuStatusTemp" }, - "type": "array", - "uniqueItems": false - } - }, - "type": "object" - }, - "body.GpuStatusTemp": { - "properties": { "main": { "type": "number" } }, - "type": "object" - }, - "body.HarborWebhook": { - "properties": { - "event_data": { - "properties": { - "repository": { - "properties": { - "date_created": { "type": "integer" }, - "name": { "type": "string" }, - "namespace": { "type": "string" }, - "repo_full_name": { "type": "string" }, - "repo_type": { "type": "string" } - }, - "type": "object" - }, - "resources": { - "items": { - "properties": { - "digest": { "type": "string" }, - "resource_url": { "type": "string" }, - "tag": { "type": "string" } - }, - "type": "object" - }, - "type": "array", - "uniqueItems": false - } - }, - "type": "object" - }, - "occur_at": { "type": "integer" }, - "operator": { "type": "string" }, - "type": { "type": "string" } - }, - "type": "object" - }, - "body.HostCapacities": { - "properties": { - "cpuCore": { "$ref": "#/components/schemas/body.CpuCoreCapacities" }, - "displayName": { "type": "string" }, - "gpu": { "$ref": "#/components/schemas/body.GpuCapacities" }, - "name": { "type": "string" }, - "ram": { "$ref": "#/components/schemas/body.RamCapacities" }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - }, - "type": "object" - }, - "body.HostRead": { - "properties": { - "displayName": { "type": "string" }, - "name": { "type": "string" }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - }, - "type": "object" - }, - "body.HostStatus": { - "properties": { - "cpu": { "$ref": "#/components/schemas/body.CpuStatus" }, - "displayName": { "type": "string" }, - "gpu": { "$ref": "#/components/schemas/body.GpuStatus" }, - "name": { "type": "string" }, - "ram": { "$ref": "#/components/schemas/body.RamStatus" }, - "zone": { - "description": "Zone is the name of the zone where the host is located.", - "type": "string" - } - }, - "type": "object" - }, - "body.HttpProxyCreate": { - "properties": { - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "name": { "maxLength": 30, "minLength": 3, "type": "string" } - }, - "required": ["name"], - "type": "object" - }, - "body.HttpProxyRead": { - "properties": { - "customDomain": { - "$ref": "#/components/schemas/body.CustomDomainRead" - }, - "name": { "type": "string" }, - "url": { "type": "string" } - }, - "type": "object" - }, - "body.HttpProxyUpdate": { - "properties": { - "customDomain": { - "description": "CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.", - "type": "string" - }, - "name": { "maxLength": 30, "minLength": 3, "type": "string" } - }, - "required": ["name"], - "type": "object" - }, - "body.JobRead": { - "properties": { - "createdAt": { "type": "string" }, - "finishedAt": { "type": "string" }, - "id": { "type": "string" }, - "lastError": { "type": "string" }, - "lastRunAt": { "type": "string" }, - "runAfter": { "type": "string" }, - "status": { "type": "string" }, - "type": { "type": "string" }, - "userId": { "type": "string" } - }, - "type": "object" - }, - "body.JobUpdate": { - "properties": { - "status": { - "enum": [ - "pending", - "running", - "failed", - "terminated", - "finished", - "completed" - ], - "type": "string" - } - }, - "type": "object" - }, - "body.K8sStats": { - "properties": { - "clusters": { - "items": { "$ref": "#/components/schemas/body.ClusterStats" }, - "type": "array", - "uniqueItems": false - }, - "podCount": { "type": "integer" } - }, - "type": "object" - }, - "body.NotificationRead": { - "properties": { - "completedAt": { "type": "string" }, - "content": { "additionalProperties": {}, "type": "object" }, - "createdAt": { "type": "string" }, - "id": { "type": "string" }, - "readAt": { "type": "string" }, - "toastedAt": { "type": "string" }, - "type": { "type": "string" }, - "userId": { "type": "string" } - }, - "type": "object" - }, - "body.NotificationUpdate": { - "properties": { - "read": { "type": "boolean" }, - "toasted": { "type": "boolean" } - }, - "type": "object" - }, - "body.PortCreate": { - "properties": { - "httpProxy": { "$ref": "#/components/schemas/body.HttpProxyCreate" }, - "name": { "maxLength": 100, "minLength": 1, "type": "string" }, - "port": { "maximum": 65535, "minimum": 1, "type": "integer" }, - "protocol": { "enum": ["tcp", "udp"], "type": "string" } - }, - "required": ["name", "port", "protocol"], - "type": "object" - }, - "body.PortRead": { - "properties": { - "externalPort": { "type": "integer" }, - "httpProxy": { "$ref": "#/components/schemas/body.HttpProxyRead" }, - "name": { "type": "string" }, - "port": { "type": "integer" }, - "protocol": { "type": "string" } - }, - "type": "object" - }, - "body.PortUpdate": { - "properties": { - "httpProxy": { "$ref": "#/components/schemas/body.HttpProxyUpdate" }, - "name": { "maxLength": 100, "minLength": 1, "type": "string" }, - "port": { "maximum": 65535, "minimum": 1, "type": "integer" }, - "protocol": { "enum": ["tcp", "udp"], "type": "string" } - }, - "required": ["name", "port", "protocol"], - "type": "object" - }, - "body.PublicKey": { - "properties": { - "key": { "type": "string" }, - "name": { "maxLength": 30, "minLength": 1, "type": "string" } - }, - "required": ["key", "name"], - "type": "object" - }, - "body.Quota": { - "properties": { - "cpuCores": { "type": "number" }, - "diskSize": { "type": "number" }, - "gpuLeaseDuration": { "description": "in hours", "type": "number" }, - "ram": { "type": "number" }, - "snapshots": { "type": "integer" } - }, - "type": "object" - }, - "body.RamCapacities": { - "properties": { "total": { "type": "integer" } }, - "type": "object" - }, - "body.RamStatus": { - "properties": { - "load": { "$ref": "#/components/schemas/body.RamStatusLoad" } - }, - "type": "object" - }, - "body.RamStatusLoad": { - "properties": { "main": { "type": "number" } }, - "type": "object" - }, - "body.ReplicaStatus": { - "properties": { - "availableReplicas": { - "description": "AvailableReplicas is the number of replicas that are available.", - "type": "integer" - }, - "desiredReplicas": { - "description": "DesiredReplicas is the number of replicas that the deployment should have.", - "type": "integer" - }, - "readyReplicas": { - "description": "ReadyReplicas is the number of replicas that are ready.", - "type": "integer" - }, - "unavailableReplicas": { - "description": "UnavailableReplicas is the number of replicas that are unavailable.", - "type": "integer" - } - }, - "type": "object" - }, - "body.ResourceMigrationCreate": { - "properties": { - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "enum": ["updateOwner"], - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.", - "properties": { "ownerId": { "type": "string" } }, - "required": ["ownerId"], - "type": "object" - } - }, - "required": ["resourceId", "type"], - "type": "object" - }, - "body.ResourceMigrationCreated": { - "properties": { - "createdAt": { "type": "string" }, - "deletedAt": { "type": "string" }, - "id": { "type": "string" }, - "jobId": { - "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.", - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "properties": { "ownerId": { "type": "string" } }, - "type": "object" - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - }, - "type": "object" - }, - "body.ResourceMigrationRead": { - "properties": { - "createdAt": { "type": "string" }, - "deletedAt": { "type": "string" }, - "id": { "type": "string" }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "properties": { "ownerId": { "type": "string" } }, - "type": "object" - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - }, - "type": "object" - }, - "body.ResourceMigrationUpdate": { - "properties": { - "code": { - "description": "Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending", - "type": "string" - } - }, - "required": ["status"], - "type": "object" - }, - "body.ResourceMigrationUpdated": { - "properties": { - "createdAt": { "type": "string" }, - "deletedAt": { "type": "string" }, - "id": { "type": "string" }, - "jobId": { - "description": "JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.", - "type": "string" - }, - "resourceId": { - "description": "ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.", - "type": "string" - }, - "resourceType": { - "description": "ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment", - "type": "string" - }, - "status": { - "description": "Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.", - "type": "string" - }, - "type": { - "description": "Type is the type of the resource migration.\n\nPossible values:\n- updateOwner", - "type": "string" - }, - "updateOwner": { - "description": "UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.", - "properties": { "ownerId": { "type": "string" } }, - "type": "object" - }, - "userId": { - "description": "UserID is the ID of the user who initiated the migration.", - "type": "string" - } - }, - "type": "object" - }, - "body.Role": { - "properties": { - "description": { "type": "string" }, - "name": { "type": "string" }, - "permissions": { - "items": { "type": "string" }, - "type": "array", - "uniqueItems": false - }, - "quota": { "$ref": "#/components/schemas/body.Quota" } - }, - "type": "object" - }, - "body.SmDeleted": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.SmRead": { - "properties": { - "createdAt": { "type": "string" }, - "id": { "type": "string" }, - "ownerId": { "type": "string" }, - "url": { "type": "string" }, - "zone": { "type": "string" } - }, - "type": "object" - }, - "body.SystemCapacities": { - "properties": { - "clusters": { - "description": "Per Cluster", - "items": { "$ref": "#/components/schemas/body.ClusterCapacities" }, - "type": "array", - "uniqueItems": false - }, - "cpuCore": { "$ref": "#/components/schemas/body.CpuCoreCapacities" }, - "gpu": { "$ref": "#/components/schemas/body.GpuCapacities" }, - "hosts": { - "description": "Per Host", - "items": { "$ref": "#/components/schemas/body.HostCapacities" }, - "type": "array", - "uniqueItems": false - }, - "ram": { "$ref": "#/components/schemas/body.RamCapacities" } - }, - "type": "object" - }, - "body.SystemStats": { - "properties": { - "k8s": { "$ref": "#/components/schemas/body.K8sStats" } - }, - "type": "object" - }, - "body.SystemStatus": { - "properties": { - "hosts": { - "items": { "$ref": "#/components/schemas/body.HostStatus" }, - "type": "array", - "uniqueItems": false - } - }, - "type": "object" - }, - "body.TeamCreate": { - "properties": { - "description": { "maxLength": 1000, "type": "string" }, - "members": { - "items": { "$ref": "#/components/schemas/body.TeamMemberCreate" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "name": { "maxLength": 100, "minLength": 1, "type": "string" }, - "resources": { - "items": { "type": "string" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - } - }, - "required": ["name"], - "type": "object" - }, - "body.TeamMember": { - "properties": { - "addedAt": { "type": "string" }, - "email": { "type": "string" }, - "firstName": { "type": "string" }, - "gravatarUrl": { "type": "string" }, - "id": { "type": "string" }, - "joinedAt": { "type": "string" }, - "lastName": { "type": "string" }, - "memberStatus": { "type": "string" }, - "teamRole": { "type": "string" }, - "username": { "type": "string" } - }, - "type": "object" - }, - "body.TeamMemberCreate": { - "properties": { - "id": { "type": "string" }, - "teamRole": { - "description": "default to MemberRoleAdmin right now", - "type": "string" - } - }, - "required": ["id"], - "type": "object" - }, - "body.TeamMemberUpdate": { - "properties": { - "id": { "type": "string" }, - "teamRole": { - "description": "default to MemberRoleAdmin right now", - "type": "string" - } - }, - "required": ["id"], - "type": "object" - }, - "body.TeamRead": { - "properties": { - "createdAt": { "type": "string" }, - "description": { "type": "string" }, - "id": { "type": "string" }, - "members": { - "items": { "$ref": "#/components/schemas/body.TeamMember" }, - "type": "array", - "uniqueItems": false - }, - "name": { "type": "string" }, - "ownerId": { "type": "string" }, - "resources": { - "items": { "$ref": "#/components/schemas/body.TeamResource" }, - "type": "array", - "uniqueItems": false - }, - "updatedAt": { "type": "string" } - }, - "type": "object" - }, - "body.TeamResource": { - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "type": { "type": "string" } - }, - "type": "object" - }, - "body.TeamUpdate": { - "properties": { - "description": { "maxLength": 1000, "type": "string" }, - "members": { - "items": { "$ref": "#/components/schemas/body.TeamMemberUpdate" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "name": { "maxLength": 100, "minLength": 1, "type": "string" }, - "resources": { - "items": { "type": "string" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - } - }, - "type": "object" - }, - "body.TimestampedSystemCapacities": { - "properties": { - "capacities": { - "$ref": "#/components/schemas/body.SystemCapacities" - }, - "timestamp": { "type": "string" } - }, - "type": "object" - }, - "body.TimestampedSystemStats": { - "properties": { - "stats": { "$ref": "#/components/schemas/body.SystemStats" }, - "timestamp": { "type": "string" } - }, - "type": "object" - }, - "body.TimestampedSystemStatus": { - "properties": { - "status": { "$ref": "#/components/schemas/body.SystemStatus" }, - "timestamp": { "type": "string" } - }, - "type": "object" - }, - "body.Usage": { - "properties": { - "cpuCores": { "type": "number" }, - "diskSize": { "type": "integer" }, - "ram": { "type": "number" } - }, - "type": "object" - }, - "body.UserData": { - "properties": { - "key": { "maxLength": 255, "minLength": 1, "type": "string" }, - "value": { "maxLength": 255, "minLength": 1, "type": "string" } - }, - "required": ["key", "value"], - "type": "object" - }, - "body.UserRead": { - "properties": { - "admin": { "type": "boolean" }, - "apiKeys": { - "items": { "$ref": "#/components/schemas/body.ApiKey" }, - "type": "array", - "uniqueItems": false - }, - "email": { "type": "string" }, - "firstName": { "type": "string" }, - "gravatarUrl": { "type": "string" }, - "id": { "type": "string" }, - "lastName": { "type": "string" }, - "publicKeys": { - "items": { "$ref": "#/components/schemas/body.PublicKey" }, - "type": "array", - "uniqueItems": false - }, - "quota": { "$ref": "#/components/schemas/body.Quota" }, - "role": { "$ref": "#/components/schemas/body.Role" }, - "storageUrl": { "type": "string" }, - "usage": { "$ref": "#/components/schemas/body.Usage" }, - "userData": { - "items": { "$ref": "#/components/schemas/body.UserData" }, - "type": "array", - "uniqueItems": false - }, - "username": { "type": "string" } - }, - "type": "object" - }, - "body.UserUpdate": { - "properties": { - "apiKeys": { - "description": "ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.", - "items": { "$ref": "#/components/schemas/body.ApiKey" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "publicKeys": { - "items": { "$ref": "#/components/schemas/body.PublicKey" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "userData": { - "items": { "$ref": "#/components/schemas/body.UserData" }, - "maxItems": 100, - "minItems": 0, - "type": "array", - "uniqueItems": false - } - }, - "type": "object" - }, - "body.VmActionCreate": { - "properties": { - "action": { - "enum": ["start", "stop", "restart", "repair"], - "type": "string" - } - }, - "required": ["action"], - "type": "object" - }, - "body.VmActionCreated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.VmCreate": { - "properties": { - "cpuCores": { "minimum": 1, "type": "integer" }, - "diskSize": { "minimum": 10, "type": "integer" }, - "name": { "maxLength": 30, "minLength": 3, "type": "string" }, - "ports": { - "items": { "$ref": "#/components/schemas/body.PortCreate" }, - "maxItems": 10, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "ram": { "minimum": 1, "type": "integer" }, - "sshPublicKey": { "type": "string" }, - "zone": { "type": "string" } - }, - "required": ["cpuCores", "diskSize", "name", "ram", "sshPublicKey"], - "type": "object" - }, - "body.VmCreated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.VmDeleted": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.VmGpuLease": { - "properties": { - "activatedAt": { - "description": "ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.", - "type": "string" - }, - "assignedAt": { - "description": "AssignedAt specifies the time when the lease was assigned to the user.", - "type": "string" - }, - "createdAt": { "type": "string" }, - "expiredAt": { - "description": "ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.", - "type": "string" - }, - "expiresAt": { - "description": "ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.", - "type": "string" - }, - "gpuGroupId": { "type": "string" }, - "id": { "type": "string" }, - "leaseDuration": { "type": "number" } - }, - "type": "object" - }, - "body.VmRead": { - "properties": { - "accessedAt": { "type": "string" }, - "createdAt": { "type": "string" }, - "gpu": { "$ref": "#/components/schemas/body.VmGpuLease" }, - "host": { "type": "string" }, - "id": { "type": "string" }, - "internalName": { "type": "string" }, - "name": { "type": "string" }, - "ownerId": { "type": "string" }, - "ports": { - "items": { "$ref": "#/components/schemas/body.PortRead" }, - "type": "array", - "uniqueItems": false - }, - "repairedAt": { "type": "string" }, - "specs": { "$ref": "#/components/schemas/body.VmSpecs" }, - "sshConnectionString": { "type": "string" }, - "sshPublicKey": { "type": "string" }, - "status": { "type": "string" }, - "teams": { - "items": { "type": "string" }, - "type": "array", - "uniqueItems": false - }, - "updatedAt": { "type": "string" }, - "zone": { "type": "string" } - }, - "type": "object" - }, - "body.VmSnapshotCreated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.VmSnapshotDeleted": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.VmSnapshotRead": { - "properties": { - "created": { "type": "string" }, - "id": { "type": "string" }, - "name": { "type": "string" }, - "status": { "type": "string" } - }, - "type": "object" - }, - "body.VmSpecs": { - "properties": { - "cpuCores": { "type": "integer" }, - "diskSize": { "type": "integer" }, - "ram": { "type": "integer" } - }, - "type": "object" - }, - "body.VmUpdate": { - "properties": { - "cpuCores": { "minimum": 1, "type": "integer" }, - "name": { "maxLength": 30, "minLength": 3, "type": "string" }, - "ports": { - "items": { "$ref": "#/components/schemas/body.PortUpdate" }, - "maxItems": 10, - "minItems": 0, - "type": "array", - "uniqueItems": false - }, - "ram": { "minimum": 1, "type": "integer" } - }, - "type": "object" - }, - "body.VmUpdated": { - "properties": { - "id": { "type": "string" }, - "jobId": { "type": "string" } - }, - "type": "object" - }, - "body.Volume": { - "properties": { - "appPath": { "maxLength": 255, "minLength": 1, "type": "string" }, - "name": { "maxLength": 30, "minLength": 3, "type": "string" }, - "serverPath": { "maxLength": 255, "minLength": 1, "type": "string" } - }, - "required": ["appPath", "name", "serverPath"], - "type": "object" - }, - "body.WorkerStatusRead": { - "properties": { - "name": { "type": "string" }, - "reportedAt": { "type": "string" }, - "status": { "type": "string" } - }, - "type": "object" - }, - "body.ZoneEndpoints": { - "properties": { - "deployment": { "type": "string" }, - "storage": { "type": "string" }, - "vm": { "type": "string" }, - "vmApp": { "type": "string" } - }, - "type": "object" - }, - "body.ZoneRead": { - "properties": { - "capabilities": { - "items": { "type": "string" }, - "type": "array", - "uniqueItems": false - }, - "description": { "type": "string" }, - "enabled": { "type": "boolean" }, - "endpoints": { "$ref": "#/components/schemas/body.ZoneEndpoints" }, - "legacy": { "type": "boolean" }, - "name": { "type": "string" } - }, - "type": "object" - }, - "sys.Error": { - "properties": { - "code": { "type": "string" }, - "msg": { "type": "string" } - }, - "type": "object" - }, - "sys.ErrorResponse": { - "properties": { - "errors": { - "items": { "$ref": "#/components/schemas/sys.Error" }, - "type": "array", - "uniqueItems": false - } - }, - "type": "object" - } - }, - "securitySchemes": { - "ApiKeyAuth": { - "flows": { - "authorizationCode": { - "authorizationUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth", - "tokenUrl": "https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token" - } - }, - "in": "header", - "type": "oauth2" - } - } - }, - "info": { - "contact": { - "name": "Support", - "url": "https://github.com/kthcloud/go-deploy" - }, - "description": "This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.", - "license": { - "name": "MIT License", - "url": "https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme" - }, - "termsOfService": "http://swagger.io/terms/", - "title": "go-deploy API", - "version": "1.0" - }, - "externalDocs": { "description": "", "url": "" }, - "paths": { - "/v2/deployments": { - "get": { - "description": "List deployments", - "parameters": [ - { - "description": "List all", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Filter by user ID", - "in": "query", - "name": "userId", - "schema": { "type": "string" } - }, - { - "description": "Include shared", - "in": "query", - "name": "shared", - "schema": { "type": "boolean" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.DeploymentRead" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List deployments", - "tags": ["Deployment"] - }, - "post": { - "description": "Create deployment", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.DeploymentCreate" } - } - }, - "description": "Deployment body", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.DeploymentRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Create deployment", - "tags": ["Deployment"] - } - }, - "/v2/deployments/{deploymentId}": { - "delete": { - "description": "Delete deployment", - "parameters": [ - { - "description": "Deployment ID", - "in": "path", - "name": "deploymentId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.DeploymentCreated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete deployment", - "tags": ["Deployment"] - }, - "get": { - "description": "Get deployment", - "parameters": [ - { - "description": "Deployment ID", - "in": "path", - "name": "deploymentId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.DeploymentRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get deployment", - "tags": ["Deployment"] - }, - "post": { - "description": "Update deployment", - "parameters": [ - { - "description": "Deployment ID", - "in": "path", - "name": "deploymentId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.DeploymentUpdate" } - } - }, - "description": "Deployment update", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.DeploymentUpdated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update deployment", - "tags": ["Deployment"] - } - }, - "/v2/deployments/{deploymentId}/ciConfig": { - "get": { - "description": "Get CI config", - "parameters": [ - { - "description": "Deployment ID", - "in": "path", - "name": "deploymentId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.CiConfig" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get CI config", - "tags": ["Deployment"] - } - }, - "/v2/deployments/{deploymentId}/command": { - "post": { - "description": "Do command", - "parameters": [ - { - "description": "Deployment ID", - "in": "path", - "name": "deploymentId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.DeploymentCommand" - } - } - }, - "description": "Command body", - "required": true - }, - "responses": { - "204": { "description": "No Content" }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "423": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Locked" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Do command", - "tags": ["Deployment"] - } - }, - "/v2/deployments/{deploymentId}/logs": { - "get": { - "description": "Get logs using Server-Sent Events", - "parameters": [ - { - "description": "Deployment ID", - "in": "path", - "name": "deploymentId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { "schema": { "type": "string" } } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get logs using Server-Sent Events", - "tags": ["Deployment"] - } - }, - "/v2/discover": { - "get": { - "description": "Discover", - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.DiscoverRead" } - } - }, - "description": "OK" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "Discover", - "tags": ["Discover"] - } - }, - "/v2/gpuGroups": { - "get": { - "description": "List GPU groups", - "parameters": [ - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.GpuGroupRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "423": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Locked" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List GPU groups", - "tags": ["GpuGroup"] - } - }, - "/v2/gpuGroups/{gpuGroupId}": { - "get": { - "description": "Get GPU group", - "parameters": [ - { - "description": "GPU group ID", - "in": "path", - "name": "gpuGroupId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.GpuGroupRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "423": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Locked" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get GPU group", - "tags": ["GpuGroup"] - } - }, - "/v2/gpuLeases": { - "get": { - "description": "List GPU leases", - "parameters": [ - { - "description": "List all", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Filter by VM ID", - "in": "query", - "name": "vmId", - "schema": { "type": "string" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.GpuLeaseRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "423": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Locked" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List GPU leases", - "tags": ["GpuLease"] - }, - "post": { - "description": "Create GPU lease", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.GpuLeaseCreate" } - } - }, - "description": "GPU lease", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.GpuLeaseCreated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Create GPU Lease", - "tags": ["GpuLease"] - } - }, - "/v2/gpuLeases/{gpuLeaseId}": { - "delete": { - "description": "Delete GPU lease", - "parameters": [ - { - "description": "GPU lease ID", - "in": "path", - "name": "gpuLeaseId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.GpuLeaseDeleted" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete GPU lease", - "tags": ["GpuLease"] - }, - "get": { - "description": "Get GPU lease", - "parameters": [ - { - "description": "GPU lease ID", - "in": "path", - "name": "gpuLeaseId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.GpuLeaseRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "423": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Locked" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get GPU lease", - "tags": ["GpuLease"] - }, - "post": { - "description": "Update GPU lease", - "parameters": [ - { - "description": "GPU lease ID", - "in": "path", - "name": "gpuLeaseId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.GpuLeaseUpdate" } - } - }, - "description": "GPU lease", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.GpuLeaseUpdated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update GPU lease", - "tags": ["GpuLease"] - } - }, - "/v2/hooks/harbor": { - "post": { - "description": "Handle Harbor hook", - "parameters": [ - { - "description": "Basic auth token", - "in": "header", - "name": "Authorization", - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.HarborWebhook" } - } - }, - "description": "Harbor webhook body", - "required": true - }, - "responses": { - "204": { "description": "No Content" }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "Handle Harbor hook", - "tags": ["Deployment"] - } - }, - "/v2/hosts": { - "get": { - "description": "List Hosts", - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.HostRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "List Hosts", - "tags": ["Host"] - } - }, - "/v2/jobs": { - "get": { - "description": "List jobs", - "parameters": [ - { - "description": "List all", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Filter by user ID", - "in": "query", - "name": "userId", - "schema": { "type": "string" } - }, - { - "description": "Filter by type", - "in": "query", - "name": "type", - "schema": { "type": "string" } - }, - { - "description": "Filter by status", - "in": "query", - "name": "status", - "schema": { "type": "string" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.JobRead" }, - "type": "array" - } - } - }, - "description": "OK" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List jobs", - "tags": ["Job"] - } - }, - "/v2/jobs/{jobId}": { - "get": { - "description": "GetJob job by id", - "parameters": [ - { - "description": "Job ID", - "in": "path", - "name": "jobId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.JobRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "GetJob job by id", - "tags": ["Job"] - }, - "post": { - "description": "Update job. Only allowed for admins.", - "parameters": [ - { - "description": "Job ID", - "in": "path", - "name": "jobId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.JobUpdate" } - } - }, - "description": "Job update", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.JobRead" } - } - }, - "description": "OK" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update job", - "tags": ["Job"] - } - }, - "/v2/metrics": { - "get": { - "description": "Get metrics", - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { "schema": { "type": "string" } } - }, - "description": "OK" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "Get metrics", - "tags": ["Metrics"] - } - }, - "/v2/notifications": { - "get": { - "description": "List notifications", - "parameters": [ - { - "description": "List all notifications", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Filter by user ID", - "in": "query", - "name": "userId", - "schema": { "type": "string" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.NotificationRead" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List notifications", - "tags": ["Notification"] - } - }, - "/v2/notifications/{notificationId}": { - "delete": { - "description": "Delete notification", - "parameters": [ - { - "description": "Notification ID", - "in": "path", - "name": "notificationId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { "schema": { "type": "object" } } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete notification", - "tags": ["Notification"] - }, - "get": { - "description": "Get notification", - "parameters": [ - { - "description": "Notification ID", - "in": "path", - "name": "notificationId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.NotificationRead" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get notification", - "tags": ["Notification"] - }, - "post": { - "description": "Update notification", - "parameters": [ - { - "description": "Notification ID", - "in": "path", - "name": "notificationId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.NotificationUpdate" - } - } - }, - "description": "Notification update", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { "schema": { "type": "object" } } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update notification", - "tags": ["Notification"] - } - }, - "/v2/register": { - "get": { - "description": "Register resource", - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "204": { "description": "No Content" }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "Register resource", - "tags": ["Register"] - } - }, - "/v2/resourceMigrations": { - "get": { - "description": "List resource migrations", - "parameters": [ - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.ResourceMigrationRead" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List resource migrations", - "tags": ["ResourceMigration"] - }, - "post": { - "description": "Create resource migration", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.ResourceMigrationCreate" - } - } - }, - "description": "Resource Migration Create", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.ResourceMigrationCreated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Create resource migration", - "tags": ["ResourceMigration"] - } - }, - "/v2/resourceMigrations/{resourceMigrationId}": { - "delete": { - "description": "Delete resource migration", - "parameters": [ - { - "description": "Resource Migration ID", - "in": "path", - "name": "resourceMigrationId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "204": { "description": "No Content" }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete resource migration", - "tags": ["ResourceMigration"] - }, - "get": { - "description": "Get resource migration", - "parameters": [ - { - "description": "Resource Migration ID", - "in": "path", - "name": "resourceMigrationId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.ResourceMigrationRead" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get resource migration", - "tags": ["ResourceMigration"] - }, - "post": { - "description": "Update resource migration", - "parameters": [ - { - "description": "Resource Migration ID", - "in": "path", - "name": "resourceMigrationId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.ResourceMigrationUpdate" - } - } - }, - "description": "Resource Migration Update", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.ResourceMigrationUpdated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update resource migration", - "tags": ["ResourceMigration"] - } - }, - "/v2/snapshots": { - "get": { - "description": "List snapshots", - "parameters": [ - { - "description": "Filter by VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.VmSnapshotRead" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "423": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Locked" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List snapshots", - "tags": ["Snapshot"] - }, - "post": { - "description": "Create snapshot", - "parameters": [ - { - "description": "VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.VmSnapshotCreated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Create snapshot", - "tags": ["Snapshot"] - } - }, - "/v2/storageManagers": { - "get": { - "description": "Get storage manager list", - "parameters": [ - { - "description": "List all", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.SmRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get storage manager list", - "tags": ["StorageManager"] - } - }, - "/v2/storageManagers/{storageManagerId}": { - "get": { - "description": "Delete storage manager", - "parameters": [ - { - "description": "Storage manager ID", - "in": "path", - "name": "storageManagerId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.SmDeleted" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete storage manager", - "tags": ["StorageManager"] - } - }, - "/v2/systemCapacities": { - "get": { - "description": "List system capacities", - "parameters": [ - { - "description": "n", - "in": "query", - "name": "n", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.TimestampedSystemCapacities" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "List system capacities", - "tags": ["System"] - } - }, - "/v2/systemStats": { - "get": { - "description": "List system stats", - "parameters": [ - { - "description": "n", - "in": "query", - "name": "n", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.TimestampedSystemStats" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "List system stats", - "tags": ["System"] - } - }, - "/v2/systemStatus": { - "get": { - "description": "List system stats", - "parameters": [ - { - "description": "n", - "in": "query", - "name": "n", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.TimestampedSystemStatus" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "List system stats", - "tags": ["System"] - } - }, - "/v2/teams": { - "get": { - "description": "List teams", - "parameters": [ - { - "description": "List all", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Filter by user ID", - "in": "query", - "name": "userId", - "schema": { "type": "string" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.TeamRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List teams", - "tags": ["Team"] - }, - "post": { - "description": "Create team", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.TeamCreate" } - } - }, - "description": "Team", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.TeamRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Create team", - "tags": ["Team"] - } - }, - "/v2/teams/{teamId}": { - "delete": { - "description": "Delete team", - "parameters": [ - { - "description": "Team ID", - "in": "path", - "name": "teamId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "204": { "description": "No Content" }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete team", - "tags": ["Team"] - }, - "get": { - "description": "Get team", - "parameters": [ - { - "description": "Team ID", - "in": "path", - "name": "teamId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.TeamRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get team", - "tags": ["Team"] - }, - "post": { - "description": "Update team", - "parameters": [ - { - "description": "Team ID", - "in": "path", - "name": "teamId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.TeamUpdate" } - } - }, - "description": "Team", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.TeamRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.BindingError" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update team", - "tags": ["Team"] - } - }, - "/v2/users": { - "get": { - "description": "List users", - "parameters": [ - { - "description": "List all", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Discovery mode", - "in": "query", - "name": "discover", - "schema": { "type": "boolean" } - }, - { - "description": "Search query", - "in": "query", - "name": "search", - "schema": { "type": "string" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.UserRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List users", - "tags": ["User"] - } - }, - "/v2/users/{userId}": { - "get": { - "description": "Get user", - "parameters": [ - { - "description": "User ID", - "in": "path", - "name": "userId", - "required": true, - "schema": { "type": "string" } - }, - { - "description": "Discovery mode", - "in": "query", - "name": "discover", - "schema": { "type": "boolean" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.UserRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get user", - "tags": ["User"] - }, - "post": { - "description": "Update user", - "parameters": [ - { - "description": "User ID", - "in": "path", - "name": "userId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.UserUpdate" } - } - }, - "description": "User update", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.UserRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update user", - "tags": ["User"] - } - }, - "/v2/users/{userId}/apiKeys": { - "post": { - "description": "Create API key", - "parameters": [ - { - "description": "User ID", - "in": "path", - "name": "userId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.ApiKeyCreate" } - } - }, - "description": "API key create body", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.ApiKeyCreated" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Create API key", - "tags": ["User"] - } - }, - "/v2/vmActions": { - "post": { - "description": "Creates a new action", - "parameters": [ - { - "description": "VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmActionCreate" } - } - }, - "description": "actions body", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.VmActionCreated" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Creates a new action", - "tags": ["VmAction"] - } - }, - "/v2/vms": { - "get": { - "description": "List VMs", - "parameters": [ - { - "description": "List all", - "in": "query", - "name": "all", - "schema": { "type": "boolean" } - }, - { - "description": "Filter by user ID", - "in": "query", - "name": "userId", - "schema": { "type": "string" } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "schema": { "type": "integer" } - }, - { - "description": "Number of items per page", - "in": "query", - "name": "pageSize", - "schema": { "type": "integer" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.VmRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List VMs", - "tags": ["VM"] - }, - "post": { - "description": "Create VM", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmCreate" } - } - }, - "description": "VM body", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmCreated" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Create VM", - "tags": ["VM"] - } - }, - "/v2/vms/{vmId}": { - "delete": { - "description": "Delete VM", - "parameters": [ - { - "description": "VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmDeleted" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete VM", - "tags": ["VM"] - }, - "get": { - "description": "Get VM", - "parameters": [ - { - "description": "VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get VM", - "tags": ["VM"] - }, - "post": { - "description": "Update VM", - "parameters": [ - { - "description": "VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmUpdate" } - } - }, - "description": "VM update", - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmUpdated" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "401": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Unauthorized" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Update VM", - "tags": ["VM"] - } - }, - "/v2/vms/{vmId}/snapshot/{snapshotId}": { - "delete": { - "description": "Delete snapshot", - "parameters": [ - { - "description": "VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - }, - { - "description": "Snapshot ID", - "in": "path", - "name": "snapshotId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/body.VmSnapshotDeleted" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Delete snapshot", - "tags": ["Snapshot"] - }, - "post": { - "description": "Get snapshot", - "parameters": [ - { - "description": "VM ID", - "in": "path", - "name": "vmId", - "required": true, - "schema": { "type": "string" } - }, - { - "description": "Snapshot ID", - "in": "path", - "name": "snapshotId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/body.VmSnapshotRead" } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "404": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Not Found" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "Get snapshot", - "tags": ["Snapshot"] - } - }, - "/v2/workerStatus": { - "get": { - "description": "List of worker status", - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/body.WorkerStatusRead" - }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "List worker status", - "tags": ["Status"] - } - }, - "/v2/zones": { - "get": { - "description": "List zones", - "requestBody": { - "content": { "application/json": { "schema": { "type": "object" } } } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { "$ref": "#/components/schemas/body.ZoneRead" }, - "type": "array" - } - } - }, - "description": "OK" - }, - "400": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Bad Request" - }, - "500": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/sys.ErrorResponse" } - } - }, - "description": "Internal Server Error" - } - }, - "security": [{ "ApiKeyAuth": [] }, { "KeycloakOAuth": [] }], - "summary": "List zones", - "tags": ["Zone"] - } - } - }, - "openapi": "3.1.0" -} + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"go-deploy API","version":"1.0"}, + "externalDocs": {"description":"","url":""}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"get":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "openapi": "3.1.0" +} \ No newline at end of file diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index e74e17a3..cdf5400e 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -1595,6 +1595,10 @@ components: type: object securitySchemes: ApiKeyAuth: + in: header + name: X-Api-Key + type: apiKey + KeycloakOAuth: flows: authorizationCode: authorizationUrl: https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth @@ -1647,11 +1651,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -1774,11 +1773,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -1855,11 +1849,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -1945,11 +1934,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -1984,11 +1968,6 @@ paths: /v2/discover: get: description: Discover - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2019,11 +1998,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2073,11 +2047,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2139,11 +2108,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2278,11 +2242,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2416,11 +2375,6 @@ paths: /v2/hosts: get: description: List Hosts - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2577,11 +2531,6 @@ paths: /v2/metrics: get: description: Get metrics - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2753,11 +2702,6 @@ paths: /v2/register: get: description: Register resource - requestBody: - content: - application/json: - schema: - type: object responses: "204": description: No Content @@ -2796,11 +2740,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -2925,11 +2864,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3028,11 +2962,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3136,11 +3065,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3184,11 +3108,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3235,11 +3154,6 @@ paths: name: "n" schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3273,11 +3187,6 @@ paths: name: "n" schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3311,11 +3220,6 @@ paths: name: "n" schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3575,11 +3479,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3622,11 +3521,6 @@ paths: name: discover schema: type: boolean - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3807,11 +3701,6 @@ paths: name: pageSize schema: type: integer - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -3958,11 +3847,6 @@ paths: required: true schema: type: string - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -4153,11 +4037,6 @@ paths: /v2/workerStatus: get: description: List of worker status - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: @@ -4185,11 +4064,6 @@ paths: /v2/zones: get: description: List zones - requestBody: - content: - application/json: - schema: - type: object responses: "200": content: diff --git a/routers/api/v2/deployment.go b/routers/api/v2/deployment.go index 7cdecf4d..78f6b427 100644 --- a/routers/api/v2/deployment.go +++ b/routers/api/v2/deployment.go @@ -26,7 +26,6 @@ import ( // @Summary Get deployment // @Description Get deployment // @Tags Deployment -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -83,7 +82,6 @@ func GetDeployment(c *gin.Context) { // @Summary List deployments // @Description List deployments // @Tags Deployment -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/deployment_ci_config.go b/routers/api/v2/deployment_ci_config.go index 0976b81d..73079fe7 100644 --- a/routers/api/v2/deployment_ci_config.go +++ b/routers/api/v2/deployment_ci_config.go @@ -15,7 +15,6 @@ import ( // @Summary Get CI config // @Description Get CI config // @Tags Deployment -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/deployment_logs.go b/routers/api/v2/deployment_logs.go index 679f416f..f6e800b2 100644 --- a/routers/api/v2/deployment_logs.go +++ b/routers/api/v2/deployment_logs.go @@ -19,7 +19,6 @@ import ( // @Summary Get logs using Server-Sent Events // @Description Get logs using Server-Sent Events // @Tags Deployment -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/discover.go b/routers/api/v2/discover.go index 8da63602..e20b2720 100644 --- a/routers/api/v2/discover.go +++ b/routers/api/v2/discover.go @@ -10,7 +10,6 @@ import ( // @Summary Discover // @Description Discover // @Tags Discover -// @Accept json // @Produce json // @Success 200 {object} body.DiscoverRead // @Failure 500 {object} sys.ErrorResponse diff --git a/routers/api/v2/gpu_group.go b/routers/api/v2/gpu_group.go index 757ab8a7..9ba65673 100644 --- a/routers/api/v2/gpu_group.go +++ b/routers/api/v2/gpu_group.go @@ -15,7 +15,6 @@ import ( // @Summary Get GPU group // @Description Get GPU group // @Tags GpuGroup -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -69,7 +68,6 @@ func GetGpuGroup(c *gin.Context) { // @Summary List GPU groups // @Description List GPU groups // @Tags GpuGroup -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/gpu_lease.go b/routers/api/v2/gpu_lease.go index 1ffa12b5..fc9b715d 100644 --- a/routers/api/v2/gpu_lease.go +++ b/routers/api/v2/gpu_lease.go @@ -21,7 +21,6 @@ import ( // @Summary Get GPU lease // @Description Get GPU lease // @Tags GpuLease -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -74,7 +73,6 @@ func GetGpuLease(c *gin.Context) { // @Summary List GPU leases // @Description List GPU leases // @Tags GpuLease -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/hosts.go b/routers/api/v2/hosts.go index 1b757042..838918fd 100644 --- a/routers/api/v2/hosts.go +++ b/routers/api/v2/hosts.go @@ -2,6 +2,7 @@ package v2 import ( "fmt" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/sys" @@ -12,7 +13,6 @@ import ( // @Summary List Hosts // @Description List Hosts // @Tags Host -// @Accept json // @Produce json // @Success 200 {array} body.HostRead // @Failure 500 {object} sys.ErrorResponse diff --git a/routers/api/v2/register.go b/routers/api/v2/register.go index 7b6352fd..ebcb28cb 100644 --- a/routers/api/v2/register.go +++ b/routers/api/v2/register.go @@ -3,6 +3,7 @@ package v2 import ( "errors" "fmt" + "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/kthcloud/go-deploy/dto/v2/body" @@ -15,7 +16,6 @@ import ( // @Summary Register resource // @Description Register resource // @Tags Register -// @Accept json // @Produce json // @Success 204 // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/resource_migration.go b/routers/api/v2/resource_migration.go index 6be1d140..fc89dcb4 100644 --- a/routers/api/v2/resource_migration.go +++ b/routers/api/v2/resource_migration.go @@ -19,7 +19,6 @@ import ( // @Summary Get resource migration // @Description Get resource migration // @Tags ResourceMigration -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -62,7 +61,6 @@ func GetResourceMigration(c *gin.Context) { // @Summary List resource migrations // @Description List resource migrations // @Tags ResourceMigration -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/sm.go b/routers/api/v2/sm.go index 7b3e408c..38b5ee24 100644 --- a/routers/api/v2/sm.go +++ b/routers/api/v2/sm.go @@ -24,7 +24,6 @@ import ( // @Summary Get storage manager // @Description Get storage manager // @Tags StorageManager -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -68,7 +67,6 @@ func GetSM(c *gin.Context) { // @Summary Get storage manager list // @Description Get storage manager list // @Tags StorageManager -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -122,7 +120,6 @@ func ListSMs(c *gin.Context) { // @Summary Delete storage manager // @Description Delete storage manager // @Tags StorageManager -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/snapshot.go b/routers/api/v2/snapshot.go index 0ece241b..ae28b62f 100644 --- a/routers/api/v2/snapshot.go +++ b/routers/api/v2/snapshot.go @@ -82,7 +82,6 @@ func GetSnapshot(c *gin.Context) { // @Summary List snapshots // @Description List snapshots // @Tags Snapshot -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/system.go b/routers/api/v2/system.go index ed896dbc..9d1c2b12 100644 --- a/routers/api/v2/system.go +++ b/routers/api/v2/system.go @@ -1,18 +1,18 @@ package v2 import ( + "net/http" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/query" "github.com/kthcloud/go-deploy/pkg/sys" "github.com/kthcloud/go-deploy/service" - "net/http" ) // ListSystemCapacities // @Summary List system capacities // @Description List system capacities // @Tags System -// @Accept json // @Produce json // @Param n query int false "n" // @Success 200 {array} body.TimestampedSystemCapacities @@ -46,7 +46,6 @@ func ListSystemCapacities(c *gin.Context) { // @Summary List system stats // @Description List system stats // @Tags System -// @Accept json // @Produce json // @Param n query int false "n" // @Success 200 {array} body.TimestampedSystemStats @@ -80,7 +79,6 @@ func ListSystemStats(c *gin.Context) { // @Summary List system stats // @Description List system stats // @Tags System -// @Accept json // @Produce json // @Param n query int false "n" // @Success 200 {array} body.TimestampedSystemStatus diff --git a/routers/api/v2/user.go b/routers/api/v2/user.go index 43ec5ec8..9a2e47aa 100644 --- a/routers/api/v2/user.go +++ b/routers/api/v2/user.go @@ -20,7 +20,6 @@ import ( // @Summary Get user // @Description Get user // @Tags User -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -100,7 +99,6 @@ func GetUser(c *gin.Context) { // @Summary List users // @Description List users // @Tags User -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/virtual_routes.go b/routers/api/v2/virtual_routes.go index a50f3586..e3e2b757 100644 --- a/routers/api/v2/virtual_routes.go +++ b/routers/api/v2/virtual_routes.go @@ -10,7 +10,6 @@ import "github.com/gin-gonic/gin" // @Summary Get metrics // @Description Get metrics // @Tags Metrics -// @Accept json // @Produce json // @Success 200 {object} string // @Failure 500 {object} sys.ErrorResponse diff --git a/routers/api/v2/vm.go b/routers/api/v2/vm.go index c375e056..962c3900 100644 --- a/routers/api/v2/vm.go +++ b/routers/api/v2/vm.go @@ -26,7 +26,6 @@ import ( // @Summary Get VM // @Description Get VM // @Tags VM -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth @@ -87,7 +86,6 @@ func GetVM(c *gin.Context) { // @Summary List VMs // @Description List VMs // @Tags VM -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth diff --git a/routers/api/v2/worker_status.go b/routers/api/v2/worker_status.go index 25fac8df..c8d91777 100644 --- a/routers/api/v2/worker_status.go +++ b/routers/api/v2/worker_status.go @@ -13,7 +13,6 @@ import ( // @Summary List worker status // @Description List of worker status // @Tags Status -// @Accept json // @Produce json // @Success 200 {array} body.WorkerStatusRead // @Failure 400 {object} sys.ErrorResponse diff --git a/routers/api/v2/zone.go b/routers/api/v2/zone.go index 62f5af97..7953da13 100644 --- a/routers/api/v2/zone.go +++ b/routers/api/v2/zone.go @@ -12,7 +12,6 @@ import ( // @Summary List zones // @Description List zones // @Tags Zone -// @Accept json // @Produce json // @Security ApiKeyAuth // @Security KeycloakOAuth From f607d69304f13b61dffcfc7b8c9e4477130c36e3 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 14:32:31 +0100 Subject: [PATCH 08/36] add caching header to the docs files --- docs/api/v2/handlers/serve_fs.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/api/v2/handlers/serve_fs.go b/docs/api/v2/handlers/serve_fs.go index da4a2b6e..e41100cf 100644 --- a/docs/api/v2/handlers/serve_fs.go +++ b/docs/api/v2/handlers/serve_fs.go @@ -11,6 +11,9 @@ import ( swaggerfiles "github.com/swaggo/files/v2" ) +// Returns a handler that serves the requested any file +// from swaggo/files/v2 embed FS with swagger UI and +// the generated doc.json (V2_swagger.json) func ServeDocs(basePath string) func(ctx *gin.Context) { return func(ctx *gin.Context) { filePath := ctx.Param("any") @@ -31,22 +34,24 @@ func ServeDocs(basePath string) func(ctx *gin.Context) { layout: "StandaloneLayout" }); };`, basePath) + ctx.Header("Cache-Control", "public, max-age=31536000") ctx.Data(http.StatusOK, "application/javascript", []byte(customScript)) return } - // Serve the Swagger documentation if strings.TrimPrefix(filePath, "/") == "doc.json" { doc, err := swag.ReadDoc("V2") if err != nil { ctx.String(http.StatusInternalServerError, "Failed to load documentation") return } + ctx.Header("Cache-Control", "public, max-age=3600") ctx.Data(http.StatusOK, "application/json", []byte(doc)) return } ctx.Request.URL.Path = filePath + ctx.Header("Cache-Control", "public, max-age=31536000") http.FileServer(http.FS(swaggerfiles.FS)).ServeHTTP(ctx.Writer, ctx.Request) } } From b24fe35a7d6dfc12a627a20a3249a5076f5a759e Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 14:46:29 +0100 Subject: [PATCH 09/36] add scruot that does linting checks --- scripts/check-lint.sh | 103 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100755 scripts/check-lint.sh diff --git a/scripts/check-lint.sh b/scripts/check-lint.sh new file mode 100755 index 00000000..94cad5ed --- /dev/null +++ b/scripts/check-lint.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color + +function get_git_root() { + git rev-parse --show-toplevel 2>/dev/null || { echo -e "${RED}This is not a git repository. Please run this script from within a Git repository.${NC}"; exit 1; } +} + +function check_gofmt() { + command -v gofmt >/dev/null 2>&1 || { echo -e "${RED}gofmt is not installed. Please install it to continue.${NC}"; exit 1; } +} + +function check_go_vet() { + command -v go >/dev/null 2>&1 || { echo -e "${RED}go is not installed. Please install Go to continue.${NC}"; exit 1; } +} + +function check_go_cyclo() { + command -v go-cyclo >/dev/null 2>&1 || { echo -e "${YELLOW}go-cyclo is not installed. Installing...${NC}"; go install github.com/fzipp/gocyclo/cmd/gocyclo@latest; } +} + +function check_ineffassign() { + command -v ineffassign >/dev/null 2>&1 || { echo -e "${YELLOW}ineffassign is not installed. Installing...${NC}"; go install github.com/gordonklaus/ineffassign@latest; } +} + +function run_gofmt() { + echo -e "${YELLOW}Running gofmt check...${NC}" + # Check for formatting issues + gofmt_output=$(gofmt -l .) + if [ -n "$gofmt_output" ]; then + echo -e "${RED}gofmt found the following issues:${NC}" + echo "$gofmt_output" + gofmt_error=1 + fi +} + +function run_go_vet() { + echo -e "${YELLOW}Running go vet check...${NC}" + # Run go vet to analyze code for potential issues + go_vet_output=$(go vet ./...) + if [ -n "$go_vet_output" ]; then + echo -e "${RED}go vet found the following issues:${NC}" + echo "$go_vet_output" + go_vet_error=1 + fi +} + +function run_go_cyclo() { + echo -e "${YELLOW}Running go-cyclo check...${NC}" + # Check for cyclomatic complexity + go_cyclo_output=$(gocyclo -over 15 .) + if [ -n "$go_cyclo_output" ]; then + echo -e "${RED}go-cyclo found the following issues:${NC}" + echo "$go_cyclo_output" + go_cyclo_error=1 + fi +} + +function run_ineffassign() { + echo -e "${YELLOW}Running ineffassign check...${NC}" + # Check for unused variable assignments + ineffassign_output=$(ineffassign .) + if [ -n "$ineffassign_output" ]; then + echo -e "${RED}ineffassign found the following issues:${NC}" + echo "$ineffassign_output" + ineffassign_error=1 + fi +} + +# Get the git root, to make sure the scripts are run in the correct location +git_root=$(get_git_root) + +# Change to the Git root directory +cd "$git_root" || { echo -e "${RED}Failed to change to the Git root directory.${NC}"; exit 1; } + +# Ensure all tools are installed +check_gofmt +check_go_vet +check_go_cyclo +check_ineffassign + +# Initialize error flags +gofmt_error=0 +go_vet_error=0 +go_cyclo_error=0 +ineffassign_error=0 + +# Execute checks +run_gofmt +run_go_vet +run_go_cyclo +run_ineffassign + +# Print a summary and exit with failure if there were any errors +if [ $gofmt_error -eq 1 ] || [ $go_vet_error -eq 1 ] || [ $go_cyclo_error -eq 1 ] || [ $ineffassign_error -eq 1 ]; then + echo -e "${RED}SUMMARY: Please resolve the above issues.${NC}" + exit 1 +else + echo -e "${GREEN}All checks passed successfully.${NC}" + exit 0 +fi From 3cefa38a9a6ad35a34660e886065983637f8a3e3 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 14:47:40 +0100 Subject: [PATCH 10/36] fix typo in script --- scripts/check-lint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-lint.sh b/scripts/check-lint.sh index 94cad5ed..8218374f 100755 --- a/scripts/check-lint.sh +++ b/scripts/check-lint.sh @@ -18,7 +18,7 @@ function check_go_vet() { } function check_go_cyclo() { - command -v go-cyclo >/dev/null 2>&1 || { echo -e "${YELLOW}go-cyclo is not installed. Installing...${NC}"; go install github.com/fzipp/gocyclo/cmd/gocyclo@latest; } + command -v gocyclo >/dev/null 2>&1 || { echo -e "${YELLOW}go-cyclo is not installed. Installing...${NC}"; go install github.com/fzipp/gocyclo/cmd/gocyclo@latest; } } function check_ineffassign() { From 8218ff5bff98486313ced89b4dc921ce3e6946aa Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 14:51:28 +0100 Subject: [PATCH 11/36] fix formatting to follow gos standard formatting --- pkg/config/config.go | 2 +- pkg/db/db.go | 2 +- pkg/db/key_value/client.go | 2 +- pkg/db/message_queue/client.go | 2 +- pkg/db/redis.go | 2 +- pkg/imp/harbor/harbor/client_test.go | 2 +- pkg/jobs/utils/utils.go | 2 +- pkg/jobs/v2/deployment_jobs.go | 2 +- pkg/jobs/v2/sm_jobs.go | 2 +- pkg/jobs/v2/vm_jobs.go | 2 +- pkg/metrics/setup.go | 2 +- scripts/check-lint.sh | 10 +++++++++- test/acc/subsystems/harbor/helpers.go | 2 +- test/acc/subsystems/harbor/project_test.go | 2 +- test/acc/subsystems/harbor/robot_test.go | 2 +- test/acc/subsystems/harbor/webhook_test.go | 2 +- test/acc/subsystems/k8s/helpers.go | 2 +- test/acc/subsystems/k8s/hpa_test.go | 2 +- test/acc/subsystems/k8s/ingress_test.go | 2 +- test/acc/subsystems/k8s/network_policy_test.go | 2 +- test/acc/subsystems/k8s/secret_test.go | 2 +- test/acc/subsystems/k8s/service_test.go | 2 +- test/acc/subsystems/k8s/vm_test.go | 2 +- test/e2e/common.go | 2 +- test/e2e/v2/deployment_utils.go | 2 +- test/e2e/v2/deployments/routes_test.go | 2 +- test/e2e/v2/gpu_leases_utils.go | 2 +- test/e2e/v2/job_utils.go | 2 +- test/e2e/v2/jobs/routes_test.go | 2 +- test/e2e/v2/notifications_utils.go | 2 +- test/e2e/v2/resource_migrations/route_test.go | 2 +- test/e2e/v2/resource_migrations_utils.go | 2 +- test/e2e/v2/sms/route_test.go | 2 +- test/e2e/v2/team_utils.go | 2 +- test/e2e/v2/teams/routes_test.go | 2 +- test/e2e/v2/user_utils.go | 2 +- test/e2e/v2/users/routes_test.go | 2 +- test/e2e/v2/vm_utils.go | 2 +- test/e2e/v2/vms/routes_test.go | 2 +- 39 files changed, 47 insertions(+), 39 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 3b03a3f2..2ca985c4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -2,13 +2,13 @@ package config import ( "fmt" - "github.com/mitchellh/mapstructure" "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/mode" "github.com/kthcloud/go-deploy/models/version" "github.com/kthcloud/go-deploy/pkg/imp/kubevirt/kubevirt" "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/pkg/subsystems/rancher" + "github.com/mitchellh/mapstructure" "gopkg.in/yaml.v3" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" diff --git a/pkg/db/db.go b/pkg/db/db.go index 8d77e558..3389a677 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -1,8 +1,8 @@ package db import ( - "github.com/redis/go-redis/v9" "github.com/kthcloud/go-deploy/pkg/log" + "github.com/redis/go-redis/v9" "go.mongodb.org/mongo-driver/mongo" ) diff --git a/pkg/db/key_value/client.go b/pkg/db/key_value/client.go index 33b95e85..89713b63 100644 --- a/pkg/db/key_value/client.go +++ b/pkg/db/key_value/client.go @@ -4,9 +4,9 @@ import ( "context" "errors" "fmt" - "github.com/redis/go-redis/v9" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/utils" + "github.com/redis/go-redis/v9" "regexp" "time" ) diff --git a/pkg/db/message_queue/client.go b/pkg/db/message_queue/client.go index 504296b7..586b3ac6 100644 --- a/pkg/db/message_queue/client.go +++ b/pkg/db/message_queue/client.go @@ -4,9 +4,9 @@ import ( "context" "encoding/json" "fmt" - "github.com/redis/go-redis/v9" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/log" + "github.com/redis/go-redis/v9" ) var ( diff --git a/pkg/db/redis.go b/pkg/db/redis.go index 2277babe..50670ce7 100644 --- a/pkg/db/redis.go +++ b/pkg/db/redis.go @@ -3,9 +3,9 @@ package db import ( "context" "fmt" - "github.com/redis/go-redis/v9" "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/log" + "github.com/redis/go-redis/v9" ) // setupRedis initializes the Redis connection. diff --git a/pkg/imp/harbor/harbor/client_test.go b/pkg/imp/harbor/harbor/client_test.go index 13adb350..8fcaf92e 100644 --- a/pkg/imp/harbor/harbor/client_test.go +++ b/pkg/imp/harbor/harbor/client_test.go @@ -7,11 +7,11 @@ import ( "testing" "github.com/go-openapi/runtime" - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/pkg/imp/harbor/harbor" "github.com/kthcloud/go-deploy/pkg/imp/harbor/harbor/test" v2client "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client" "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/health" + "github.com/stretchr/testify/assert" ) var ( diff --git a/pkg/jobs/utils/utils.go b/pkg/jobs/utils/utils.go index 290e2029..69b2c8d9 100644 --- a/pkg/jobs/utils/utils.go +++ b/pkg/jobs/utils/utils.go @@ -3,13 +3,13 @@ package utils import ( "context" "fmt" - "github.com/mitchellh/mapstructure" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/service/core" + "github.com/mitchellh/mapstructure" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "golang.org/x/exp/slices" diff --git a/pkg/jobs/v2/deployment_jobs.go b/pkg/jobs/v2/deployment_jobs.go index a996a9f1..61be53a2 100644 --- a/pkg/jobs/v2/deployment_jobs.go +++ b/pkg/jobs/v2/deployment_jobs.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "github.com/mitchellh/mapstructure" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" @@ -15,6 +14,7 @@ import ( "github.com/kthcloud/go-deploy/pkg/services/confirm" "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/mitchellh/mapstructure" "time" ) diff --git a/pkg/jobs/v2/sm_jobs.go b/pkg/jobs/v2/sm_jobs.go index 50857981..ca59dbd0 100644 --- a/pkg/jobs/v2/sm_jobs.go +++ b/pkg/jobs/v2/sm_jobs.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "github.com/mitchellh/mapstructure" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" @@ -13,6 +12,7 @@ import ( "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" + "github.com/mitchellh/mapstructure" "time" ) diff --git a/pkg/jobs/v2/vm_jobs.go b/pkg/jobs/v2/vm_jobs.go index 149833e4..13332413 100644 --- a/pkg/jobs/v2/vm_jobs.go +++ b/pkg/jobs/v2/vm_jobs.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "github.com/mitchellh/mapstructure" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" @@ -16,6 +15,7 @@ import ( "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/v2/vms/opts" + "github.com/mitchellh/mapstructure" "time" ) diff --git a/pkg/metrics/setup.go b/pkg/metrics/setup.go index 023ab994..59033c3b 100644 --- a/pkg/metrics/setup.go +++ b/pkg/metrics/setup.go @@ -2,9 +2,9 @@ package metrics import ( "fmt" - "github.com/penglongli/gin-metrics/ginmetrics" "github.com/kthcloud/go-deploy/pkg/db/key_value" "github.com/kthcloud/go-deploy/utils" + "github.com/penglongli/gin-metrics/ginmetrics" "strconv" ) diff --git a/scripts/check-lint.sh b/scripts/check-lint.sh index 8218374f..1ee7a710 100755 --- a/scripts/check-lint.sh +++ b/scripts/check-lint.sh @@ -33,6 +33,8 @@ function run_gofmt() { echo -e "${RED}gofmt found the following issues:${NC}" echo "$gofmt_output" gofmt_error=1 + else + echo -e "${GREEN}passed gofmt.${NC}" fi } @@ -44,6 +46,8 @@ function run_go_vet() { echo -e "${RED}go vet found the following issues:${NC}" echo "$go_vet_output" go_vet_error=1 + else + echo -e "${GREEN}passed go vet.${NC}" fi } @@ -52,9 +56,11 @@ function run_go_cyclo() { # Check for cyclomatic complexity go_cyclo_output=$(gocyclo -over 15 .) if [ -n "$go_cyclo_output" ]; then - echo -e "${RED}go-cyclo found the following issues:${NC}" + echo -e "${RED}gocyclo found the following issues:${NC}" echo "$go_cyclo_output" go_cyclo_error=1 + else + echo -e "${GREEN}passed gocyclo -over 15.${NC}" fi } @@ -66,6 +72,8 @@ function run_ineffassign() { echo -e "${RED}ineffassign found the following issues:${NC}" echo "$ineffassign_output" ineffassign_error=1 + else + echo -e "${GREEN}passed ineffassign.${NC}" fi } diff --git a/test/acc/subsystems/harbor/helpers.go b/test/acc/subsystems/harbor/helpers.go index 4d8e36ec..7cf72f99 100644 --- a/test/acc/subsystems/harbor/helpers.go +++ b/test/acc/subsystems/harbor/helpers.go @@ -1,12 +1,12 @@ package harbor import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/subsystems/harbor" "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/acc" + "github.com/stretchr/testify/assert" "strings" "testing" ) diff --git a/test/acc/subsystems/harbor/project_test.go b/test/acc/subsystems/harbor/project_test.go index 6dabe91c..73ea498b 100644 --- a/test/acc/subsystems/harbor/project_test.go +++ b/test/acc/subsystems/harbor/project_test.go @@ -1,8 +1,8 @@ package harbor import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/test" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/harbor/robot_test.go b/test/acc/subsystems/harbor/robot_test.go index a6ca0f46..f32b42c8 100644 --- a/test/acc/subsystems/harbor/robot_test.go +++ b/test/acc/subsystems/harbor/robot_test.go @@ -1,10 +1,10 @@ package harbor import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/pkg/subsystems/harbor/models" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/acc" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/harbor/webhook_test.go b/test/acc/subsystems/harbor/webhook_test.go index f2ca2ca0..1089168f 100644 --- a/test/acc/subsystems/harbor/webhook_test.go +++ b/test/acc/subsystems/harbor/webhook_test.go @@ -1,9 +1,9 @@ package harbor import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/acc" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/k8s/helpers.go b/test/acc/subsystems/k8s/helpers.go index 24d8930f..82a87316 100644 --- a/test/acc/subsystems/k8s/helpers.go +++ b/test/acc/subsystems/k8s/helpers.go @@ -1,12 +1,12 @@ package k8s import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/acc" + "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" "testing" ) diff --git a/test/acc/subsystems/k8s/hpa_test.go b/test/acc/subsystems/k8s/hpa_test.go index 68a4a8e3..884826b1 100644 --- a/test/acc/subsystems/k8s/hpa_test.go +++ b/test/acc/subsystems/k8s/hpa_test.go @@ -1,8 +1,8 @@ package k8s import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/test" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/k8s/ingress_test.go b/test/acc/subsystems/k8s/ingress_test.go index a1c9d8f8..68744424 100644 --- a/test/acc/subsystems/k8s/ingress_test.go +++ b/test/acc/subsystems/k8s/ingress_test.go @@ -1,9 +1,9 @@ package k8s import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/acc" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/k8s/network_policy_test.go b/test/acc/subsystems/k8s/network_policy_test.go index bcc65c6a..14f407a4 100644 --- a/test/acc/subsystems/k8s/network_policy_test.go +++ b/test/acc/subsystems/k8s/network_policy_test.go @@ -1,8 +1,8 @@ package k8s import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/k8s/secret_test.go b/test/acc/subsystems/k8s/secret_test.go index bc9334e9..79b3ba83 100644 --- a/test/acc/subsystems/k8s/secret_test.go +++ b/test/acc/subsystems/k8s/secret_test.go @@ -1,9 +1,9 @@ package k8s import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/acc" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/k8s/service_test.go b/test/acc/subsystems/k8s/service_test.go index da7fa69c..1c67e0ea 100644 --- a/test/acc/subsystems/k8s/service_test.go +++ b/test/acc/subsystems/k8s/service_test.go @@ -1,8 +1,8 @@ package k8s import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/test" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/acc/subsystems/k8s/vm_test.go b/test/acc/subsystems/k8s/vm_test.go index 041fb4f6..9cdcd872 100644 --- a/test/acc/subsystems/k8s/vm_test.go +++ b/test/acc/subsystems/k8s/vm_test.go @@ -1,9 +1,9 @@ package k8s import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/acc" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/e2e/common.go b/test/e2e/common.go index e937553b..4892ee6d 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -5,10 +5,10 @@ import ( "encoding/json" "fmt" "github.com/google/uuid" - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/stretchr/testify/assert" "io" "net/http" "strings" diff --git a/test/e2e/v2/deployment_utils.go b/test/e2e/v2/deployment_utils.go index 8b5e8fe2..a516ee25 100644 --- a/test/e2e/v2/deployment_utils.go +++ b/test/e2e/v2/deployment_utils.go @@ -2,12 +2,12 @@ package v2 import ( "crypto/tls" - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/app/status_codes" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "golang.org/x/net/idna" "net/http" "strconv" diff --git a/test/e2e/v2/deployments/routes_test.go b/test/e2e/v2/deployments/routes_test.go index 55be2322..1c313300 100644 --- a/test/e2e/v2/deployments/routes_test.go +++ b/test/e2e/v2/deployments/routes_test.go @@ -2,11 +2,11 @@ package deployments import ( "github.com/google/uuid" - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" "github.com/kthcloud/go-deploy/test/e2e/v2" + "github.com/stretchr/testify/assert" "net/http" "os" "strconv" diff --git a/test/e2e/v2/gpu_leases_utils.go b/test/e2e/v2/gpu_leases_utils.go index 0fa996fb..b431ef66 100644 --- a/test/e2e/v2/gpu_leases_utils.go +++ b/test/e2e/v2/gpu_leases_utils.go @@ -1,9 +1,9 @@ package v2 import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/e2e/v2/job_utils.go b/test/e2e/v2/job_utils.go index 2f2f1e65..9a0bb63b 100644 --- a/test/e2e/v2/job_utils.go +++ b/test/e2e/v2/job_utils.go @@ -1,10 +1,10 @@ package v2 import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/app/status_codes" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "net/http" "testing" ) diff --git a/test/e2e/v2/jobs/routes_test.go b/test/e2e/v2/jobs/routes_test.go index e15ff830..c1416813 100644 --- a/test/e2e/v2/jobs/routes_test.go +++ b/test/e2e/v2/jobs/routes_test.go @@ -1,11 +1,11 @@ package jobs import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" "github.com/kthcloud/go-deploy/test/e2e/v2" + "github.com/stretchr/testify/assert" "os" "testing" ) diff --git a/test/e2e/v2/notifications_utils.go b/test/e2e/v2/notifications_utils.go index 56fd01f5..f20f4f46 100644 --- a/test/e2e/v2/notifications_utils.go +++ b/test/e2e/v2/notifications_utils.go @@ -1,9 +1,9 @@ package v2 import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/e2e/v2/resource_migrations/route_test.go b/test/e2e/v2/resource_migrations/route_test.go index 48a964fb..dbf01ae9 100644 --- a/test/e2e/v2/resource_migrations/route_test.go +++ b/test/e2e/v2/resource_migrations/route_test.go @@ -1,11 +1,11 @@ package resource_migrations import ( - "github.com/stretchr/testify/assert" bodyV2 "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" v2 "github.com/kthcloud/go-deploy/test/e2e/v2" + "github.com/stretchr/testify/assert" "os" "strings" "testing" diff --git a/test/e2e/v2/resource_migrations_utils.go b/test/e2e/v2/resource_migrations_utils.go index 4c80849a..2b5fb347 100644 --- a/test/e2e/v2/resource_migrations_utils.go +++ b/test/e2e/v2/resource_migrations_utils.go @@ -1,10 +1,10 @@ package v2 import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "net/http" "testing" ) diff --git a/test/e2e/v2/sms/route_test.go b/test/e2e/v2/sms/route_test.go index f7fdcf6c..09e600af 100644 --- a/test/e2e/v2/sms/route_test.go +++ b/test/e2e/v2/sms/route_test.go @@ -1,11 +1,11 @@ package sms import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" "github.com/kthcloud/go-deploy/test/e2e/v2" + "github.com/stretchr/testify/assert" "os" "testing" "time" diff --git a/test/e2e/v2/team_utils.go b/test/e2e/v2/team_utils.go index 3d9f05fb..6a4dbb60 100644 --- a/test/e2e/v2/team_utils.go +++ b/test/e2e/v2/team_utils.go @@ -1,11 +1,11 @@ package v2 import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "net/http" "testing" ) diff --git a/test/e2e/v2/teams/routes_test.go b/test/e2e/v2/teams/routes_test.go index c18b6b88..0ae1e34b 100644 --- a/test/e2e/v2/teams/routes_test.go +++ b/test/e2e/v2/teams/routes_test.go @@ -1,11 +1,11 @@ package teams import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" "github.com/kthcloud/go-deploy/test/e2e/v2" + "github.com/stretchr/testify/assert" "net/http" "os" "testing" diff --git a/test/e2e/v2/user_utils.go b/test/e2e/v2/user_utils.go index a0b472fb..93ca4f11 100644 --- a/test/e2e/v2/user_utils.go +++ b/test/e2e/v2/user_utils.go @@ -1,10 +1,10 @@ package v2 import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "testing" ) diff --git a/test/e2e/v2/users/routes_test.go b/test/e2e/v2/users/routes_test.go index 8111add8..16a94af1 100644 --- a/test/e2e/v2/users/routes_test.go +++ b/test/e2e/v2/users/routes_test.go @@ -1,11 +1,11 @@ package users import ( - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" "github.com/kthcloud/go-deploy/test/e2e/v2" + "github.com/stretchr/testify/assert" "os" "testing" "time" diff --git a/test/e2e/v2/vm_utils.go b/test/e2e/v2/vm_utils.go index 77ffbf58..d4293fb0 100644 --- a/test/e2e/v2/vm_utils.go +++ b/test/e2e/v2/vm_utils.go @@ -3,10 +3,10 @@ package v2 import ( "fmt" "github.com/helloyi/go-sshclient" - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/app/status_codes" "github.com/kthcloud/go-deploy/test/e2e" + "github.com/stretchr/testify/assert" "net/http" "os" "strings" diff --git a/test/e2e/v2/vms/routes_test.go b/test/e2e/v2/vms/routes_test.go index 68b3456b..56df2ea7 100644 --- a/test/e2e/v2/vms/routes_test.go +++ b/test/e2e/v2/vms/routes_test.go @@ -2,11 +2,11 @@ package vms import ( "github.com/google/uuid" - "github.com/stretchr/testify/assert" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test/e2e" "github.com/kthcloud/go-deploy/test/e2e/v2" + "github.com/stretchr/testify/assert" "net/http" "os" "strings" From d83c390c1584608e2aa93e217ce8899bbe56e163 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 14:54:47 +0100 Subject: [PATCH 12/36] fix go vet check in script --- scripts/check-lint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/check-lint.sh b/scripts/check-lint.sh index 1ee7a710..91bba1ad 100755 --- a/scripts/check-lint.sh +++ b/scripts/check-lint.sh @@ -6,7 +6,7 @@ YELLOW='\033[0;33m' NC='\033[0m' # No Color function get_git_root() { - git rev-parse --show-toplevel 2>/dev/null || { echo -e "${RED}This is not a git repository. Please run this script from within a Git repository.${NC}"; exit 1; } + git rev-parse --show-toplevel 2>/dev/null || { echo -e "${RED}This is not a git repository. Please run this script from within the Git repository.${NC}"; exit 1; } } function check_gofmt() { @@ -41,7 +41,7 @@ function run_gofmt() { function run_go_vet() { echo -e "${YELLOW}Running go vet check...${NC}" # Run go vet to analyze code for potential issues - go_vet_output=$(go vet ./...) + go_vet_output=$(go vet ./... 2>&1) if [ -n "$go_vet_output" ]; then echo -e "${RED}go vet found the following issues:${NC}" echo "$go_vet_output" From 6577ae0827087aba70b7ec2b54539f1150173e94 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 16:10:09 +0100 Subject: [PATCH 13/36] pass go vet --- pkg/db/base.go | 21 +++--- pkg/db/migrate/migrate.go | 3 +- pkg/db/mongo.go | 7 +- .../base_clients/activity_resource_client.go | 25 ++++--- .../resources/base_clients/resource_client.go | 49 +++++++------ pkg/db/resources/deployment_repo/client.go | 29 ++++---- pkg/db/resources/deployment_repo/db.go | 72 +++++++++--------- pkg/db/resources/gpu_group_repo/client.go | 2 +- pkg/db/resources/gpu_group_repo/db.go | 5 +- pkg/db/resources/gpu_lease_repo/client.go | 15 ++-- pkg/db/resources/gpu_lease_repo/db.go | 21 +++--- pkg/db/resources/host_repo/client.go | 11 +-- pkg/db/resources/host_repo/db.go | 21 +++--- pkg/db/resources/job_repo/client.go | 19 ++--- pkg/db/resources/job_repo/db.go | 65 +++++++++-------- pkg/db/resources/notification_repo/client.go | 6 +- pkg/db/resources/notification_repo/db.go | 11 +-- .../resource_migration_repo/client.go | 12 +-- .../resources/resource_migration_repo/db.go | 5 +- pkg/db/resources/sm_repo/client.go | 8 +- pkg/db/resources/sm_repo/db.go | 25 ++++--- pkg/db/resources/team_repo/client.go | 17 +++-- pkg/db/resources/team_repo/db.go | 17 +++-- pkg/db/resources/user_repo/client.go | 13 ++-- pkg/db/resources/user_repo/db.go | 33 +++++---- pkg/db/resources/vm_port_repo/client.go | 14 ++-- pkg/db/resources/vm_port_repo/db.go | 43 +++++------ pkg/db/resources/vm_repo/client.go | 21 +++--- pkg/db/resources/vm_repo/db.go | 73 ++++++++++++------- pkg/db/resources/worker_status_repo/db.go | 15 ++-- pkg/jobs/utils/utils.go | 11 +-- .../status_update/vm_status_listener.go | 3 +- pkg/services/synchronize/fetch_gpu.go | 15 ++-- routers/api/v2/snapshot.go | 32 ++------ scripts/check-lint.sh | 22 +++++- service/v2/deployments/deployment_service.go | 7 +- .../resource_migration_service.go | 3 +- service/v2/sms/sm_service.go | 9 ++- service/v2/teams/team_service.go | 7 +- service/v2/vms/k8s_service/k8s_service.go | 5 +- service/v2/vms/vm_service.go | 9 ++- 41 files changed, 432 insertions(+), 369 deletions(-) diff --git a/pkg/db/base.go b/pkg/db/base.go index 9493c4aa..843b9d04 100644 --- a/pkg/db/base.go +++ b/pkg/db/base.go @@ -4,12 +4,13 @@ import ( "context" "errors" "fmt" + "reflect" + "time" + "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "reflect" - "time" ) type Resource interface { @@ -19,7 +20,7 @@ type onlyID struct { ID string `bson:"id"` } -var UniqueConstraintErr = errors.New("unique constraint error") +var ErrUniqueConstraint = errors.New("unique constraint error") func AddIfNotNil(data *bson.D, key string, value interface{}) { if value == nil || (reflect.ValueOf(value).Kind() == reflect.Ptr && reflect.ValueOf(value).IsNil()) { @@ -40,7 +41,7 @@ func GroupFilters(filter bson.D, extraFilter bson.M, searchParams *SearchParams, // extra filter if extraFilter != nil { - filter = bson.D{{"$and", bson.A{filter, extraFilter}}} + filter = bson.D{{Key: "$and", Value: bson.A{filter, extraFilter}}} } // search filter @@ -51,7 +52,7 @@ func GroupFilters(filter bson.D, extraFilter bson.M, searchParams *SearchParams, searchFilter = append(searchFilter, bson.M{field: bson.M{"$regex": pattern, "$options": "i"}}) } - return bson.D{{"$and", bson.A{filter, bson.D{{"$or", searchFilter}}}}} + return bson.D{{Key: "$and", Value: bson.A{filter, bson.D{{Key: "$or", Value: searchFilter}}}}} } else { return filter } @@ -60,7 +61,7 @@ func GroupFilters(filter bson.D, extraFilter bson.M, searchParams *SearchParams, func AddExcludeDeletedFilter(filter bson.D) bson.D { newFilter := filter - newFilter = append(newFilter, bson.E{Key: "deletedAt", Value: bson.D{{"$in", bson.A{nil, time.Time{}}}}}) + newFilter = append(newFilter, bson.E{Key: "deletedAt", Value: bson.D{{Key: "$in", Value: bson.A{nil, time.Time{}}}}}) return newFilter } @@ -98,7 +99,7 @@ func ListResources[T any](collection *mongo.Collection, filter bson.D, projectio } if sortBy != nil { - findOptions.SetSort(bson.D{{sortBy.Field, sortBy.Order}}) + findOptions.SetSort(bson.D{{Key: sortBy.Field, Value: sortBy.Order}}) } if projection != nil { @@ -144,11 +145,11 @@ func CountDistinctResources(collection *mongo.Collection, field string, filter b func CreateIfUniqueResource[T Resource](collection *mongo.Collection, id string, data *T, filter bson.D) error { result, err := collection.UpdateOne(context.TODO(), filter, bson.D{ - {"$setOnInsert", data}, + {Key: "$setOnInsert", Value: data}, }, options.Update().SetUpsert(true)) if err != nil { if mongo.IsDuplicateKeyError(err) { - return UniqueConstraintErr + return ErrUniqueConstraint } return fmt.Errorf("failed to create unique model. details: %w", err) @@ -171,7 +172,7 @@ func CreateIfUniqueResource[T Resource](collection *mongo.Collection, id string, } } - return UniqueConstraintErr + return ErrUniqueConstraint } return nil diff --git a/pkg/db/migrate/migrate.go b/pkg/db/migrate/migrate.go index 99174bfd..e784982f 100644 --- a/pkg/db/migrate/migrate.go +++ b/pkg/db/migrate/migrate.go @@ -2,6 +2,7 @@ package migrator import ( "fmt" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" "github.com/kthcloud/go-deploy/pkg/log" @@ -59,7 +60,7 @@ func migratePrivateBooleanToVisibilityEnum_2024_06_10() error { mainApp.Visibility = model.VisibilityPublic } - err = deployment_repo.New().SetWithBsonByID(deployment.ID, bson.D{{"apps.main.visibility", mainApp.Visibility}}) + err = deployment_repo.New().SetWithBsonByID(deployment.ID, bson.D{{Key: "apps.main.visibility", Value: mainApp.Visibility}}) if err != nil { return err } diff --git a/pkg/db/mongo.go b/pkg/db/mongo.go index 6606b135..89a6dc50 100644 --- a/pkg/db/mongo.go +++ b/pkg/db/mongo.go @@ -3,13 +3,14 @@ package db import ( "context" "fmt" + "strings" + "time" + "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/log" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "strings" - "time" ) // CollectionDefinition is a struct that defines a collection. @@ -82,7 +83,7 @@ func (dbCtx *Context) setupMongo() error { _, err = DB.GetCollection(def.Name).Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: keys, - Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.D{{"deletedAt", bson.D{{"$in", []interface{}{nil, time.Time{}}}}}}), + Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.D{{Key: "deletedAt", Value: bson.D{{Key: "$in", Value: []interface{}{nil, time.Time{}}}}}}), }) if err != nil && !isIndexExistsError(err) { return makeError(err) diff --git a/pkg/db/resources/base_clients/activity_resource_client.go b/pkg/db/resources/base_clients/activity_resource_client.go index 81184014..470c9807 100644 --- a/pkg/db/resources/base_clients/activity_resource_client.go +++ b/pkg/db/resources/base_clients/activity_resource_client.go @@ -3,11 +3,12 @@ package base_clients import ( "context" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "time" ) // ActivityResourceClient is a type of base client that adds methods to manage activities in the database. @@ -35,9 +36,9 @@ func (client *ActivityResourceClient[T]) AddExtraFilter(filter bson.D) *Activity // If the activity already exists, it will be overwritten. func (client *ActivityResourceClient[T]) AddActivity(id, activity string) error { _, err := client.Collection.UpdateOne(context.TODO(), - bson.D{{"id", id}}, - bson.D{{"$set", bson.D{ - {"activities." + activity, model.Activity{ + bson.D{{Key: "id", Value: id}}, + bson.D{{Key: "$set", Value: bson.D{ + {Key: "activities." + activity, Value: model.Activity{ Name: activity, CreatedAt: time.Now(), }}, @@ -54,9 +55,9 @@ func (client *ActivityResourceClient[T]) AddActivity(id, activity string) error // If the activity does not exist, nothing will happen. func (client *ActivityResourceClient[T]) RemoveActivity(id, activity string) error { _, err := client.Collection.UpdateOne(context.TODO(), - bson.D{{"id", id}}, - bson.D{{"$unset", bson.D{ - {"activities." + activity, ""}, + bson.D{{Key: "id", Value: id}}, + bson.D{{Key: "$unset", Value: bson.D{ + {Key: "activities." + activity, Value: ""}, }}}, ) if err != nil { @@ -69,9 +70,9 @@ func (client *ActivityResourceClient[T]) RemoveActivity(id, activity string) err // ClearActivities clears all activities from the model with the given ID. func (client *ActivityResourceClient[T]) ClearActivities(id string) error { _, err := client.Collection.UpdateOne(context.TODO(), - bson.D{{"id", id}}, - bson.D{{"$set", bson.D{ - {"activities", make(map[string]model.Activity)}, + bson.D{{Key: "id", Value: id}}, + bson.D{{Key: "$set", Value: bson.D{ + {Key: "activities", Value: make(map[string]model.Activity)}, }}}, ) if err != nil { @@ -85,8 +86,8 @@ func (client *ActivityResourceClient[T]) ClearActivities(id string) error { // IsDoingActivity returns whether the model with the given ID is doing the given activity. func (client *ActivityResourceClient[T]) IsDoingActivity(id, activity string) (bool, error) { filter := bson.D{ - {"id", id}, - {"activities." + activity, bson.M{ + {Key: "id", Value: id}, + {Key: "activities." + activity, Value: bson.M{ "$exists": true, }}, } diff --git a/pkg/db/resources/base_clients/resource_client.go b/pkg/db/resources/base_clients/resource_client.go index bf215663..496c9c57 100644 --- a/pkg/db/resources/base_clients/resource_client.go +++ b/pkg/db/resources/base_clients/resource_client.go @@ -2,10 +2,11 @@ package base_clients import ( "fmt" + "time" + "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "time" ) type Resource interface { @@ -37,12 +38,12 @@ func (client *ResourceClient[T]) AddExtraFilter(filter bson.D) *ResourceClient[T // GetByID returns a model with the given ID. func (client *ResourceClient[T]) GetByID(id string) (*T, error) { - return db.GetResource[T](client.Collection, db.GroupFilters(bson.D{{"id", id}}, client.ExtraFilter, client.Search, client.IncludeDeleted), nil) + return db.GetResource[T](client.Collection, db.GroupFilters(bson.D{{Key: "id", Value: id}}, client.ExtraFilter, client.Search, client.IncludeDeleted), nil) } // GetByName returns a model with the given name. func (client *ResourceClient[T]) GetByName(name string) (*T, error) { - return db.GetResource[T](client.Collection, db.GroupFilters(bson.D{{"name", name}}, client.ExtraFilter, client.Search, client.IncludeDeleted), nil) + return db.GetResource[T](client.Collection, db.GroupFilters(bson.D{{Key: "name", Value: name}}, client.ExtraFilter, client.Search, client.IncludeDeleted), nil) } // List returns any resources that match the given filter. @@ -52,7 +53,7 @@ func (client *ResourceClient[T]) List() ([]T, error) { // ExistsByID returns whether a model with the given ID exists. func (client *ResourceClient[T]) ExistsByID(id string) (bool, error) { - count, err := db.CountResources(client.Collection, db.GroupFilters(bson.D{{"id", id}}, client.ExtraFilter, client.Search, client.IncludeDeleted)) + count, err := db.CountResources(client.Collection, db.GroupFilters(bson.D{{Key: "id", Value: id}}, client.ExtraFilter, client.Search, client.IncludeDeleted)) if err != nil { return false, err } @@ -62,7 +63,7 @@ func (client *ResourceClient[T]) ExistsByID(id string) (bool, error) { // ExistsByName returns whether a model with the given name exists. func (client *ResourceClient[T]) ExistsByName(name string) (bool, error) { - count, err := db.CountResources(client.Collection, db.GroupFilters(bson.D{{"name", name}}, client.ExtraFilter, client.Search, client.IncludeDeleted)) + count, err := db.CountResources(client.Collection, db.GroupFilters(bson.D{{Key: "name", Value: name}}, client.ExtraFilter, client.Search, client.IncludeDeleted)) if err != nil { return false, err } @@ -103,12 +104,12 @@ func (client *ResourceClient[T]) UpdateWithBSON(update bson.D) error { // UpdateWithBsonByID updates a model with the given ID and BSON update. func (client *ResourceClient[T]) UpdateWithBsonByID(id string, update bson.D) error { - return client.UpdateWithBsonByFilter(bson.D{{"id", id}}, update) + return client.UpdateWithBsonByFilter(bson.D{{Key: "id", Value: id}}, update) } // UpdateWithBsonByName updates a model with the given name and BSON update. func (client *ResourceClient[T]) UpdateWithBsonByName(name string, update bson.D) error { - return client.UpdateWithBsonByFilter(bson.D{{"name", name}}, update) + return client.UpdateWithBsonByFilter(bson.D{{Key: "name", Value: name}}, update) } // UpdateWithBsonByFilter updates a model with the given filter and BSON update. @@ -119,7 +120,7 @@ func (client *ResourceClient[T]) UpdateWithBsonByFilter(filter bson.D, update bs // UnsetWithBSON unsets the given fields from a model. func (client *ResourceClient[T]) UnsetWithBSON(fields ...string) error { update := bson.D{ - {"$unset", bson.D{}}, + {Key: "$unset", Value: bson.D{}}, } for _, field := range fields { @@ -132,7 +133,7 @@ func (client *ResourceClient[T]) UnsetWithBSON(fields ...string) error { // UnsetByID unsets the given fields from a model with the given ID. func (client *ResourceClient[T]) UnsetByID(id string, fields ...string) error { update := bson.D{ - {"$unset", bson.D{}}, + {Key: "$unset", Value: bson.D{}}, } for _, field := range fields { @@ -145,7 +146,7 @@ func (client *ResourceClient[T]) UnsetByID(id string, fields ...string) error { // UnsetByName unsets the given fields from a model with the given name. func (client *ResourceClient[T]) UnsetByName(name string, fields ...string) error { update := bson.D{ - {"$unset", bson.D{}}, + {Key: "$unset", Value: bson.D{}}, } for _, field := range fields { @@ -157,22 +158,22 @@ func (client *ResourceClient[T]) UnsetByName(name string, fields ...string) erro // SetWithBSON sets the given fields to the given values in a model. func (client *ResourceClient[T]) SetWithBSON(update bson.D) error { - return client.UpdateWithBSON(bson.D{{"$set", update}}) + return client.UpdateWithBSON(bson.D{{Key: "$set", Value: update}}) } // SetWithBsonByID sets the given fields to the given values in a model with the given ID. func (client *ResourceClient[T]) SetWithBsonByID(id string, update bson.D) error { - return client.UpdateWithBsonByID(id, bson.D{{"$set", update}}) + return client.UpdateWithBsonByID(id, bson.D{{Key: "$set", Value: update}}) } // SetWithBsonByName sets the given fields to the given values in a model with the given name. func (client *ResourceClient[T]) SetWithBsonByName(name string, update bson.D) error { - return client.UpdateWithBsonByName(name, bson.D{{"$set", update}}) + return client.UpdateWithBsonByName(name, bson.D{{Key: "$set", Value: update}}) } // SetWithBsonByFilter sets the given fields to the given values in a model with the given filter. func (client *ResourceClient[T]) SetWithBsonByFilter(filter bson.D, update bson.D) error { - return client.UpdateWithBsonByFilter(filter, bson.D{{"$set", update}}) + return client.UpdateWithBsonByFilter(filter, bson.D{{Key: "$set", Value: update}}) } // CountDistinct returns the number of distinct values for the given field. @@ -186,7 +187,7 @@ func (client *ResourceClient[T]) CountDistinct(field string) (int, error) { // does not remove the resources from the database. func (client *ResourceClient[T]) Delete() error { update := bson.D{ - {"$set", bson.D{{"deletedAt", time.Now()}}}, + {Key: "$set", Value: bson.D{{Key: "deletedAt", Value: time.Now()}}}, } err := client.UpdateWithBSON(update) @@ -203,7 +204,7 @@ func (client *ResourceClient[T]) Delete() error { // does not remove the model from the database. func (client *ResourceClient[T]) DeleteByID(id string) error { update := bson.D{ - {"$set", bson.D{{"deletedAt", time.Now()}}}, + {Key: "$set", Value: bson.D{{Key: "deletedAt", Value: time.Now()}}}, } err := client.UpdateWithBsonByID(id, update) @@ -217,8 +218,8 @@ func (client *ResourceClient[T]) DeleteByID(id string) error { // Deleted returns whether a model with the given ID has been deleted. func (client *ResourceClient[T]) Deleted(id string) (bool, error) { filter := bson.D{ - {"id", id}, - {"deletedAt", bson.M{"$nin": []interface{}{nil, time.Time{}}}}, + {Key: "id", Value: id}, + {Key: "deletedAt", Value: bson.M{"$nin": []interface{}{nil, time.Time{}}}}, } count, err := db.CountResources(client.Collection, db.GroupFilters(filter, client.ExtraFilter, client.Search, true)) if err != nil { @@ -237,7 +238,7 @@ func (client *ResourceClient[T]) Erase() error { // EraseByID deletes a model with the given ID. // It removes the model from the database. func (client *ResourceClient[T]) EraseByID(id string) error { - return db.DeleteResources(client.Collection, db.GroupFilters(bson.D{{"id", id}}, client.ExtraFilter, client.Search, client.IncludeDeleted)) + return db.DeleteResources(client.Collection, db.GroupFilters(bson.D{{Key: "id", Value: id}}, client.ExtraFilter, client.Search, client.IncludeDeleted)) } // Get returns a model with the given filter. @@ -264,7 +265,7 @@ type OnlyName struct { // GetID returns the ID of a model with the given filter. // It returns a OnlyID type, which only contains the ID. func (client *ResourceClient[T]) GetID() (*string, error) { - projection := bson.D{{"id", 1}} + projection := bson.D{{Key: "id", Value: 1}} idStruct, err := db.GetResource[OnlyID](client.Collection, db.GroupFilters(bson.D{}, client.ExtraFilter, client.Search, client.IncludeDeleted), projection) if err != nil { @@ -281,9 +282,9 @@ func (client *ResourceClient[T]) GetID() (*string, error) { // GetName returns the name of a model with the given filter. // It returns a OnlyName type, which only contains the name. func (client *ResourceClient[T]) GetName(id string) (*string, error) { - projection := bson.D{{"name", 1}} + projection := bson.D{{Key: "name", Value: 1}} - nameStruct, err := db.GetResource[OnlyName](client.Collection, db.GroupFilters(bson.D{{"id", id}}, client.ExtraFilter, client.Search, client.IncludeDeleted), projection) + nameStruct, err := db.GetResource[OnlyName](client.Collection, db.GroupFilters(bson.D{{Key: "id", Value: id}}, client.ExtraFilter, client.Search, client.IncludeDeleted), projection) if err != nil { return nil, err } @@ -297,7 +298,7 @@ func (client *ResourceClient[T]) GetName(id string) (*string, error) { // ListIDs returns the IDs of all resources that match the given filter. func (client *ResourceClient[T]) ListIDs() ([]string, error) { - projection := bson.D{{"id", 1}} + projection := bson.D{{Key: "id", Value: 1}} ids, err := db.ListResources[OnlyID](client.Collection, db.GroupFilters(nil, client.ExtraFilter, client.Search, client.IncludeDeleted), projection, client.Pagination, client.SortBy) if err != nil { return nil, err @@ -313,7 +314,7 @@ func (client *ResourceClient[T]) ListIDs() ([]string, error) { // ListNames returns the names of all resources that match the given filter. func (client *ResourceClient[T]) ListNames() ([]string, error) { - projection := bson.D{{"name", 1}} + projection := bson.D{{Key: "name", Value: 1}} names, err := db.ListResources[OnlyName](client.Collection, db.GroupFilters(nil, client.ExtraFilter, client.Search, client.IncludeDeleted), projection, client.Pagination, client.SortBy) if err != nil { return nil, err diff --git a/pkg/db/resources/deployment_repo/client.go b/pkg/db/resources/deployment_repo/client.go index 8dfe4b7e..7932c4c2 100644 --- a/pkg/db/resources/deployment_repo/client.go +++ b/pkg/db/resources/deployment_repo/client.go @@ -1,12 +1,13 @@ package deployment_repo import ( + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "time" ) // Client is used to manage deployments in the database. @@ -51,8 +52,8 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // ExcludeIDs adds a filter to the client to exclude the given IDs. func (client *Client) ExcludeIDs(ids ...string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"id", bson.D{{"$nin", ids}}}}) - client.ActivityResourceClient.AddExtraFilter(bson.D{{"id", bson.D{{"$nin", ids}}}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "id", Value: bson.D{{Key: "$nin", Value: ids}}}}) + client.ActivityResourceClient.AddExtraFilter(bson.D{{Key: "id", Value: bson.D{{Key: "$nin", Value: ids}}}}) return client } @@ -66,7 +67,7 @@ func (client *Client) IncludeDeletedResources() *Client { // WithOwner adds a filter to the client to only include deployments with the given owner ID. func (client *Client) WithOwner(ownerID string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"ownerId", ownerID}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "ownerId", Value: ownerID}}) client.ActivityResourceClient.ExtraFilter = client.ResourceClient.ExtraFilter client.RestrictUserID = &ownerID @@ -86,7 +87,7 @@ func (client *Client) WithActivities(activities ...string) *Client { } filter := bson.D{{ - "$or", andFilter, + Key: "$or", Value: andFilter, }} client.ResourceClient.AddExtraFilter(filter) @@ -108,7 +109,7 @@ func (client *Client) WithoutActivities(activities ...string) *Client { } filter := bson.D{{ - "$and", andFilter, + Key: "$and", Value: andFilter, }} client.ResourceClient.AddExtraFilter(filter) @@ -120,7 +121,7 @@ func (client *Client) WithoutActivities(activities ...string) *Client { // WithNoActivities adds a filter to the client to only include deployments without any activities. func (client *Client) WithNoActivities() *Client { filter := bson.D{{ - "activities", bson.M{ + Key: "activities", Value: bson.M{ "$gte": bson.M{}, }, }} @@ -133,7 +134,7 @@ func (client *Client) WithNoActivities() *Client { // WithNameRegex adds a filter to the client to only include deployments with a name matching the given regex. func (client *Client) WithNameRegex(name string) *Client { - filter := bson.D{{"name", bson.D{{"$regex", name}}}} + filter := bson.D{{Key: "name", Value: bson.D{{Key: "$regex", Value: name}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -143,7 +144,7 @@ func (client *Client) WithNameRegex(name string) *Client { // OlderThan adds a filter to the client to only include deployments created before the given timestamp. func (client *Client) OlderThan(timestamp time.Time) *Client { - filter := bson.D{{"createdAt", bson.D{{"$lt", timestamp}}}} + filter := bson.D{{Key: "createdAt", Value: bson.D{{Key: "$lt", Value: timestamp}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -153,7 +154,7 @@ func (client *Client) OlderThan(timestamp time.Time) *Client { // WithPendingCustomDomain adds a filter to the client to only include deployments with a pending custom domain. func (client *Client) WithPendingCustomDomain() *Client { - filter := bson.D{{"apps.main.customDomain.status", bson.D{{"$ne", model.CustomDomainStatusActive}}}} + filter := bson.D{{Key: "apps.main.customDomain.status", Value: bson.D{{Key: "$ne", Value: model.CustomDomainStatusActive}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -163,7 +164,7 @@ func (client *Client) WithPendingCustomDomain() *Client { // WithZone adds a filter to the client to only include deployments in the given zone. func (client *Client) WithZone(zone ...string) *Client { - filter := bson.D{{"zone", bson.D{{"$in", zone}}}} + filter := bson.D{{Key: "zone", Value: bson.D{{Key: "$in", Value: zone}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -173,7 +174,7 @@ func (client *Client) WithZone(zone ...string) *Client { // LastAccessedBefore adds a filter to the client to only include deployments that were last accessed before the given timestamp. func (client *Client) LastAccessedBefore(timestamp time.Time) *Client { - filter := bson.D{{"accessedAt", bson.D{{"$lt", timestamp}}}} + filter := bson.D{{Key: "accessedAt", Value: bson.D{{Key: "$lt", Value: timestamp}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -183,7 +184,7 @@ func (client *Client) LastAccessedBefore(timestamp time.Time) *Client { // Enabled adds a filter to the client to only include deployments that are enabled. func (client *Client) Enabled() *Client { - filter := bson.D{{"apps.main.replicas", bson.D{{"$gt", 0}}}} + filter := bson.D{{Key: "apps.main.replicas", Value: bson.D{{Key: "$gt", Value: 0}}}} client.ResourceClient.AddExtraFilter(filter) @@ -192,7 +193,7 @@ func (client *Client) Enabled() *Client { // Disabled adds a filter to the client to only include deployments that are disabled. func (client *Client) Disabled() *Client { - filter := bson.D{{"apps.main.replicas", 0}} + filter := bson.D{{Key: "apps.main.replicas", Value: 0}} client.ResourceClient.AddExtraFilter(filter) diff --git a/pkg/db/resources/deployment_repo/db.go b/pkg/db/resources/deployment_repo/db.go index f7da4a33..dd33866c 100644 --- a/pkg/db/resources/deployment_repo/db.go +++ b/pkg/db/resources/deployment_repo/db.go @@ -4,6 +4,9 @@ import ( "context" "errors" "fmt" + "sort" + "time" + "github.com/google/uuid" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/app/status_codes" @@ -14,8 +17,6 @@ import ( "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "sort" - "time" ) // Create creates a new deployment with the given params. @@ -68,7 +69,10 @@ func (client *Client) Create(id, ownerID string, params *model.DeploymentCreateP DeletedAt: time.Time{}, AccessedAt: time.Now(), - Activities: map[string]model.Activity{model.ActivityBeingCreated: {model.ActivityBeingCreated, time.Now()}}, + Activities: map[string]model.Activity{model.ActivityBeingCreated: { + Name: model.ActivityBeingCreated, + CreatedAt: time.Now(), + }}, Apps: map[string]model.App{appName: mainApp}, Subsystems: model.DeploymentSubsystems{}, Logs: make([]model.Log, 0), @@ -140,8 +144,8 @@ func (client *Client) UpdateWithParams(id string, params *model.DeploymentUpdate err = client.UpdateWithBsonByID(id, bson.D{ - {"$set", setUpdate}, - {"$unset", unsetUpdate}, + {Key: "$set", Value: setUpdate}, + {Key: "$unset", Value: unsetUpdate}, }, ) if err != nil { @@ -158,14 +162,14 @@ func (client *Client) UpdateWithParams(id string, params *model.DeploymentUpdate // GetLogs returns the last NLogsCache logs for a deployment func (client *Client) GetLogs(id string, history int) ([]model.Log, error) { projection := bson.D{ - {"logs", bson.D{ - {"$slice", -history}, + {Key: "logs", Value: bson.D{ + {Key: "$slice", Value: -history}, }}, } var deployment model.Deployment err := client.Collection.FindOne(context.TODO(), - bson.D{{"id", id}}, + bson.D{{Key: "id", Value: id}}, options.FindOne().SetProjection(projection), ).Decode(&deployment) if err != nil { @@ -182,13 +186,13 @@ func (client *Client) GetLogs(id string, history int) ([]model.Log, error) { // GetLogsAfter returns the logs after the given time, with a maximum of NLogsCache logs. func (client *Client) GetLogsAfter(id string, createdAt time.Time) ([]model.Log, error) { projection := bson.D{ - {"logs", bson.D{ - {"$slice", -model.NLogsCache}, + {Key: "logs", Value: bson.D{ + {Key: "$slice", Value: -model.NLogsCache}, }}, } filter := bson.D{ - {"id", id}, + {Key: "id", Value: id}, } deployment, err := client.GetWithFilterAndProjection(filter, projection) @@ -218,10 +222,10 @@ func (client *Client) AddLogsByName(name string, logs ...model.Log) error { }) update := bson.D{ - {"$push", bson.D{ - {"logs", bson.D{ - {"$each", logs}, - {"$slice", -model.NLogsCache}, + {Key: "$push", Value: bson.D{ + {Key: "logs", Value: bson.D{ + {Key: "$each", Value: logs}, + {Key: "$slice", Value: -model.NLogsCache}, }}, }}, } @@ -237,10 +241,10 @@ func (client *Client) AddLogsByName(name string, logs ...model.Log) error { // GetUsage returns the total usage of all deployments. func (client *Client) GetUsage() (*model.DeploymentUsage, error) { projection := bson.D{ - {"_id", 0}, - {"apps.main.replicas", 1}, - {"apps.main.cpuCores", 1}, - {"apps.main.ram", 1}, + {Key: "_id", Value: 0}, + {Key: "apps.main.replicas", Value: 1}, + {Key: "apps.main.cpuCores", Value: 1}, + {Key: "apps.main.ram", Value: 1}, } deployments, err := client.ListWithFilterAndProjection(bson.D{}, projection) @@ -263,8 +267,8 @@ func (client *Client) GetUsage() (*model.DeploymentUsage, error) { // SetStatusByName sets the status of a deployment. func (client *Client) SetStatusByName(name, status string, replicaStatus *model.ReplicaStatus) error { update := bson.D{ - {"status", status}, - {"apps.main.replicaStatus", replicaStatus}, + {Key: "status", Value: status}, + {Key: "apps.main.replicaStatus", Value: replicaStatus}, } return client.SetWithBsonByName(name, update) @@ -272,7 +276,7 @@ func (client *Client) SetStatusByName(name, status string, replicaStatus *model. // SetErrorByName sets the error of a deployment. func (client *Client) SetErrorByName(name string, error *model.DeploymentError) error { - return client.SetWithBsonByName(name, bson.D{{"error", error}}) + return client.SetWithBsonByName(name, bson.D{{Key: "error", Value: error}}) } // UnsetErrorByName unsets the error of a deployment. @@ -284,23 +288,23 @@ func (client *Client) UnsetErrorByName(name string) error { // It prepends the key with `subsystems` and unsets it. func (client *Client) DeleteSubsystem(id, key string) error { subsystemKey := fmt.Sprintf("subsystems.%s", key) - return client.UpdateWithBsonByID(id, bson.D{{"$unset", bson.D{{subsystemKey, ""}}}}) + return client.UpdateWithBsonByID(id, bson.D{{Key: "$unset", Value: bson.D{{Key: subsystemKey, Value: ""}}}}) } // SetSubsystem updates a subsystem from a deployment. // It prepends the key with `subsystems` and sets it. func (client *Client) SetSubsystem(id, key string, update interface{}) error { subsystemKey := fmt.Sprintf("subsystems.%s", key) - return client.SetWithBsonByID(id, bson.D{{subsystemKey, update}}) + return client.SetWithBsonByID(id, bson.D{{Key: subsystemKey, Value: update}}) } // MarkRepaired marks a deployment as repaired. // It sets RepairedAt and unsets the repairing activity. func (client *Client) MarkRepaired(id string) error { - filter := bson.D{{"id", id}} + filter := bson.D{{Key: "id", Value: id}} update := bson.D{ - {"$set", bson.D{{"repairedAt", time.Now()}}}, - {"$unset", bson.D{{"activities.repairing", ""}}}, + {Key: "$set", Value: bson.D{{Key: "repairedAt", Value: time.Now()}}}, + {Key: "$unset", Value: bson.D{{Key: "activities.repairing", Value: ""}}}, } _, err := client.Collection.UpdateOne(context.TODO(), filter, update) @@ -314,10 +318,10 @@ func (client *Client) MarkRepaired(id string) error { // MarkUpdated marks a deployment as updated. // It sets UpdatedAt and unsets the updating activity. func (client *Client) MarkUpdated(id string) error { - filter := bson.D{{"id", id}} + filter := bson.D{{Key: "id", Value: id}} update := bson.D{ - {"$set", bson.D{{"updatedAt", time.Now()}}}, - {"$unset", bson.D{{"activities.updating", ""}}}, + {Key: "$set", Value: bson.D{{Key: "updatedAt", Value: time.Now()}}}, + {Key: "$unset", Value: bson.D{{Key: "activities.updating", Value: ""}}}, } _, err := client.Collection.UpdateOne(context.TODO(), filter, update) @@ -330,15 +334,15 @@ func (client *Client) MarkUpdated(id string) error { // MarkAccessed marks a deployment as accessed to the current time. func (client *Client) MarkAccessed(id string) error { - return client.SetWithBsonByID(id, bson.D{{"accessedAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "accessedAt", Value: time.Now()}}) } // UpdateCustomDomainStatus updates the status of a custom domain, such as // CustomDomainStatusActive, CustomDomainStatusVerificationFailed, CustomDomainStatusPending func (client *Client) UpdateCustomDomainStatus(id string, status string) error { - filter := bson.D{{"id", id}} + filter := bson.D{{Key: "id", Value: id}} update := bson.D{ - {"$set", bson.D{{"apps.main.customDomain.status", status}}}, + {Key: "$set", Value: bson.D{{Key: "apps.main.customDomain.status", Value: status}}}, } _, err := client.Collection.UpdateOne(context.TODO(), filter, update) @@ -361,7 +365,7 @@ func (client *Client) SetPingResult(id string, pingResult int) error { return nil } - err = client.UpdateWithBsonByID(id, bson.D{{"$set", bson.D{{"apps.main.pingResult", pingResult}}}}) + err = client.UpdateWithBsonByID(id, bson.D{{Key: "$set", Value: bson.D{{Key: "apps.main.pingResult", Value: pingResult}}}}) if err != nil { return fmt.Errorf("failed to update deployment ping result %s. details: %w", id, err) } diff --git a/pkg/db/resources/gpu_group_repo/client.go b/pkg/db/resources/gpu_group_repo/client.go index 9093ab50..b4af4882 100644 --- a/pkg/db/resources/gpu_group_repo/client.go +++ b/pkg/db/resources/gpu_group_repo/client.go @@ -33,7 +33,7 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // WithZone adds a filter to the client to only include groups with the given zone. func (client *Client) WithZone(zone string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"zone", zone}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "zone", Value: zone}}) return client } diff --git a/pkg/db/resources/gpu_group_repo/db.go b/pkg/db/resources/gpu_group_repo/db.go index 6387399c..7178f211 100644 --- a/pkg/db/resources/gpu_group_repo/db.go +++ b/pkg/db/resources/gpu_group_repo/db.go @@ -3,6 +3,7 @@ package gpu_group_repo import ( "errors" "fmt" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/utils" @@ -24,9 +25,9 @@ func (client *Client) Create(name, displayName, zone, vendor, deviceID, vendorID } // We assume there is a unique constraint on name + zone - err := client.CreateIfUnique(id, &group, bson.D{{"id", id}, {"zone", zone}}) + err := client.CreateIfUnique(id, &group, bson.D{{Key: "id", Value: id}, {Key: "zone", Value: zone}}) if err != nil { - if errors.Is(err, db.UniqueConstraintErr) { + if errors.Is(err, db.ErrUniqueConstraint) { return GpuLeaseAlreadyExistsErr } diff --git a/pkg/db/resources/gpu_lease_repo/client.go b/pkg/db/resources/gpu_lease_repo/client.go index d85a7035..444e3063 100644 --- a/pkg/db/resources/gpu_lease_repo/client.go +++ b/pkg/db/resources/gpu_lease_repo/client.go @@ -1,11 +1,12 @@ package gpu_lease_repo import ( + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" - "time" ) // Client is used to manage GPU leases in the database. @@ -34,35 +35,35 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // WithGroupName adds a filter to the client to only include leases with the given group name. func (client *Client) WithGroupName(groupName string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"groupName", groupName}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "groupName", Value: groupName}}) return client } // WithVmID adds a filter to the client to only include leases with the given VM ID. func (client *Client) WithVmID(vmID string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"vmId", vmID}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "vmId", Value: vmID}}) return client } // WithGpuGroupID adds a filter to the client to only include leases with the given GPU group ID. func (client *Client) WithGpuGroupID(gpuGroupID string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"gpuGroupId", gpuGroupID}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "gpuGroupId", Value: gpuGroupID}}) return client } // CreatedBefore adds a filter to the client to only include leases created before the given time. func (client *Client) CreatedBefore(createdBefore time.Time) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"createdAt", bson.D{{"$lt", createdBefore}}}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "createdAt", Value: bson.D{{Key: "$lt", Value: createdBefore}}}}) return client } // WithUserID adds a filter to the client to only include leases with the given user ID. func (client *Client) WithUserID(userID string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"userId", userID}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "userId", Value: userID}}) return client } @@ -70,7 +71,7 @@ func (client *Client) WithUserID(userID string) *Client { // OnlyActive adds a filter to the client to only include active leases. func (client *Client) OnlyActive() *Client { // An active lease is one that has a expiresAt field set - filter := bson.D{{"expiresAt", bson.D{{"$exists", true}}}} + filter := bson.D{{Key: "expiresAt", Value: bson.D{{Key: "$exists", Value: true}}}} client.ResourceClient.AddExtraFilter(filter) return client diff --git a/pkg/db/resources/gpu_lease_repo/db.go b/pkg/db/resources/gpu_lease_repo/db.go index 7a0336e2..9a1f9ba0 100644 --- a/pkg/db/resources/gpu_lease_repo/db.go +++ b/pkg/db/resources/gpu_lease_repo/db.go @@ -2,10 +2,11 @@ package gpu_lease_repo import ( "errors" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" - "time" ) func (client *Client) Create(id, userID, groupName string, leaseDuration float64) error { @@ -23,9 +24,9 @@ func (client *Client) Create(id, userID, groupName string, leaseDuration float64 } // Right now we only allow one lease per user. We assume there is a unique index set up for this. - err := client.CreateIfUnique(id, &lease, bson.D{{"userId", userID}}) + err := client.CreateIfUnique(id, &lease, bson.D{{Key: "userId", Value: userID}}) if err != nil { - if errors.Is(err, db.UniqueConstraintErr) { + if errors.Is(err, db.ErrUniqueConstraint) { return GpuLeaseAlreadyExistsErr } @@ -43,7 +44,7 @@ func (client *Client) UpdateWithParams(id string, params *model.GpuLeaseUpdatePa err := client.SetWithBsonByID(id, update) if err != nil { - if errors.Is(err, db.UniqueConstraintErr) { + if errors.Is(err, db.ErrUniqueConstraint) { return VmAlreadyAttachedErr } @@ -54,25 +55,25 @@ func (client *Client) UpdateWithParams(id string, params *model.GpuLeaseUpdatePa } func (client *Client) Release() error { - return client.SetWithBSON(bson.D{{"vmId", nil}}) + return client.SetWithBSON(bson.D{{Key: "vmId", Value: nil}}) } func (client *Client) ReleaseByID(id string) error { - return client.SetWithBsonByID(id, bson.D{{"vmId", nil}}) + return client.SetWithBsonByID(id, bson.D{{Key: "vmId", Value: nil}}) } func (client *Client) SetExpiry(id string, expiresAt time.Time) error { - return client.SetWithBsonByID(id, bson.D{{"expiresAt", expiresAt}}) + return client.SetWithBsonByID(id, bson.D{{Key: "expiresAt", Value: expiresAt}}) } func (client *Client) MarkExpired(id string) error { - return client.SetWithBsonByID(id, bson.D{{"expiredAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "expiredAt", Value: time.Now()}}) } func (client *Client) MarkAssigned(id string) error { - return client.SetWithBsonByID(id, bson.D{{"assignedAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "assignedAt", Value: time.Now()}}) } func (client *Client) MarkActivated(id string) error { - return client.SetWithBsonByID(id, bson.D{{"activatedAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "activatedAt", Value: time.Now()}}) } diff --git a/pkg/db/resources/host_repo/client.go b/pkg/db/resources/host_repo/client.go index 406e4317..d598f6ca 100644 --- a/pkg/db/resources/host_repo/client.go +++ b/pkg/db/resources/host_repo/client.go @@ -1,11 +1,12 @@ package host_repo import ( + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" - "time" ) // Client is the client for the host model. @@ -37,9 +38,9 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // Activated adds a filter to only return activated hosts func (client *Client) Activated() *Client { - filter := bson.D{{"$or", bson.A{ - bson.D{{"deactivatedUntil", bson.D{{"$lt", time.Now()}}}}, - bson.D{{"deactivatedUntil", bson.D{{"$exists", false}}}}, + filter := bson.D{{Key: "$or", Value: bson.A{ + bson.D{{Key: "deactivatedUntil", Value: bson.D{{Key: "$lt", Value: time.Now()}}}}, + bson.D{{Key: "deactivatedUntil", Value: bson.D{{Key: "$exists", Value: false}}}}, }}} client.AddExtraFilter(filter) @@ -49,7 +50,7 @@ func (client *Client) Activated() *Client { // Schedulable adds a filter to only return hosts that are schedulable func (client *Client) Schedulable() *Client { - filter := bson.D{{"schedulable", true}} + filter := bson.D{{Key: "schedulable", Value: true}} client.AddExtraFilter(filter) diff --git a/pkg/db/resources/host_repo/db.go b/pkg/db/resources/host_repo/db.go index f592498e..7b74269d 100644 --- a/pkg/db/resources/host_repo/db.go +++ b/pkg/db/resources/host_repo/db.go @@ -3,9 +3,10 @@ package host_repo import ( "context" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "go.mongodb.org/mongo-driver/bson" - "time" ) func (client *Client) Register(host *model.Host) error { @@ -30,16 +31,16 @@ func (client *Client) Register(host *model.Host) error { // Host exists, update it update := bson.D{ - {"displayName", host.DisplayName}, - {"zone", host.Zone}, + {Key: "displayName", Value: host.DisplayName}, + {Key: "zone", Value: host.Zone}, - {"ip", host.IP}, - {"port", host.Port}, + {Key: "ip", Value: host.IP}, + {Key: "port", Value: host.Port}, - {"lastSeenAt", time.Now()}, + {Key: "lastSeenAt", Value: time.Now()}, - {"enabled", host.Enabled}, - {"schedulable", host.Schedulable}, + {Key: "enabled", Value: host.Enabled}, + {Key: "schedulable", Value: host.Schedulable}, } err = client.SetWithBsonByName(host.Name, update) @@ -51,7 +52,7 @@ func (client *Client) Register(host *model.Host) error { } func (client *Client) MarkSchedulable(name string, schedulable bool) error { - return client.SetWithBsonByName(name, bson.D{{"schedulable", schedulable}}) + return client.SetWithBsonByName(name, bson.D{{Key: "schedulable", Value: schedulable}}) } func (client *Client) DeactivateHost(name string, until ...time.Time) error { @@ -62,5 +63,5 @@ func (client *Client) DeactivateHost(name string, until ...time.Time) error { deactivatedUntil = time.Now().AddDate(1000, 0, 0) // 1000 years is sort of forever ;) } - return client.SetWithBsonByName(name, bson.D{{"deactivatedUntil", deactivatedUntil}}) + return client.SetWithBsonByName(name, bson.D{{Key: "deactivatedUntil", Value: deactivatedUntil}}) } diff --git a/pkg/db/resources/job_repo/client.go b/pkg/db/resources/job_repo/client.go index 1ad6adaf..49ea9a4d 100644 --- a/pkg/db/resources/job_repo/client.go +++ b/pkg/db/resources/job_repo/client.go @@ -1,11 +1,12 @@ package job_repo import ( + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" - "time" ) // Client is used to manage jobs in the database. @@ -27,14 +28,14 @@ func New() *Client { // ExcludeScheduled adds a filter to the client to exclude scheduled jobs. func (client *Client) ExcludeScheduled() *Client { - client.AddExtraFilter(bson.D{{"runAfter", bson.D{{"$lte", time.Now()}}}}) + client.AddExtraFilter(bson.D{{Key: "runAfter", Value: bson.D{{Key: "$lte", Value: time.Now()}}}}) return client } // ExcludeIDs adds a filter to the client to exclude the given IDs. func (client *Client) ExcludeIDs(ids ...string) *Client { - client.AddExtraFilter(bson.D{{"id", bson.D{{"$nin", ids}}}}) + client.AddExtraFilter(bson.D{{Key: "id", Value: bson.D{{Key: "$nin", Value: ids}}}}) return client } @@ -48,35 +49,35 @@ func (client *Client) AddFilter(filter bson.D) *Client { // IncludeTypes adds a filter to the client to only include jobs with the given types. func (client *Client) IncludeTypes(types ...string) *Client { - client.AddExtraFilter(bson.D{{"type", bson.D{{"$in", types}}}}) + client.AddExtraFilter(bson.D{{Key: "type", Value: bson.D{{Key: "$in", Value: types}}}}) return client } // IncludeStatus adds a filter to the client to only include jobs with the given status. func (client *Client) IncludeStatus(status ...string) *Client { - client.AddExtraFilter(bson.D{{"status", bson.D{{"$in", status}}}}) + client.AddExtraFilter(bson.D{{Key: "status", Value: bson.D{{Key: "$in", Value: status}}}}) return client } // ExcludeStatus adds a filter to the client to exclude the given status. func (client *Client) ExcludeStatus(status ...string) *Client { - client.AddExtraFilter(bson.D{{"status", bson.D{{"$nin", status}}}}) + client.AddExtraFilter(bson.D{{Key: "status", Value: bson.D{{Key: "$nin", Value: status}}}}) return client } // ExcludeTypes adds a filter to the client to exclude the given types. func (client *Client) ExcludeTypes(types ...string) *Client { - client.AddExtraFilter(bson.D{{"type", bson.D{{"$nin", types}}}}) + client.AddExtraFilter(bson.D{{Key: "type", Value: bson.D{{Key: "$nin", Value: types}}}}) return client } // FilterArgs adds a filter to the client to only include jobs with the given args. func (client *Client) FilterArgs(argName string, filter interface{}) *Client { - client.AddExtraFilter(bson.D{{"args." + argName, filter}}) + client.AddExtraFilter(bson.D{{Key: "args." + argName, Value: filter}}) return client } @@ -103,7 +104,7 @@ func (client *Client) WithSort(field string, order int) *Client { // WithUserID adds a filter to the client to only include jobs with the given user ID. func (client *Client) WithUserID(userID string) *Client { - client.AddExtraFilter(bson.D{{"userId", userID}}) + client.AddExtraFilter(bson.D{{Key: "userId", Value: userID}}) client.RestrictUserID = &userID return client diff --git a/pkg/db/resources/job_repo/db.go b/pkg/db/resources/job_repo/db.go index 1c04052c..22113bf1 100644 --- a/pkg/db/resources/job_repo/db.go +++ b/pkg/db/resources/job_repo/db.go @@ -4,12 +4,13 @@ import ( "context" "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "time" ) // Create creates a new job in the database. @@ -53,11 +54,11 @@ func (client *Client) CreateScheduled(id, userID, jobType, version string, runAf func (client *Client) GetNext() (*model.Job, error) { now := time.Now() filter := bson.D{ - {"status", model.JobStatusPending}, - {"runAfter", bson.D{{"$lte", now}}}, + {Key: "status", Value: model.JobStatusPending}, + {Key: "runAfter", Value: bson.D{{Key: "$lte", Value: now}}}, } - opts := options.FindOneAndUpdate().SetSort(bson.D{{"createdAt", -1}}) - update := bson.D{{"$set", bson.D{{"status", model.JobStatusRunning}, {"lastRunAt", time.Now()}}}} + opts := options.FindOneAndUpdate().SetSort(bson.D{{Key: "createdAt", Value: -1}}) + update := bson.D{{Key: "$set", Value: bson.D{{Key: "status", Value: model.JobStatusRunning}, {Key: "lastRunAt", Value: time.Now()}}}} var job model.Job err := client.Collection.FindOneAndUpdate(context.TODO(), filter, update, opts).Decode(&job) @@ -76,11 +77,11 @@ func (client *Client) GetNext() (*model.Job, error) { func (client *Client) GetNextFailed() (*model.Job, error) { now := time.Now() filter := bson.D{ - {"status", model.JobStatusFailed}, - {"runAfter", bson.D{{"$lte", now}}}, + {Key: "status", Value: model.JobStatusFailed}, + {Key: "runAfter", Value: bson.D{{Key: "$lte", Value: now}}}, } - opts := options.FindOneAndUpdate().SetSort(bson.D{{"createdAt", -1}}) - update := bson.D{{"$set", bson.D{{"status", model.JobStatusRunning}, {"lastRunAt", time.Now()}}}} + opts := options.FindOneAndUpdate().SetSort(bson.D{{Key: "createdAt", Value: -1}}) + update := bson.D{{Key: "$set", Value: bson.D{{Key: "status", Value: model.JobStatusRunning}, {Key: "lastRunAt", Value: time.Now()}}}} var job model.Job err := client.Collection.FindOneAndUpdate(context.TODO(), filter, update, opts).Decode(&job) @@ -97,14 +98,14 @@ func (client *Client) GetNextFailed() (*model.Job, error) { // MarkCompleted marks a job as completed. func (client *Client) MarkCompleted(jobID string) error { - filter := bson.D{{"id", jobID}} + filter := bson.D{{Key: "id", Value: jobID}} // update status and finishedAt update := bson.D{ - {"$set", - bson.D{ - {"status", model.JobStatusCompleted}, - {"finishedAt", time.Now()}, + {Key: "$set", + Value: bson.D{ + {Key: "status", Value: model.JobStatusCompleted}, + {Key: "finishedAt", Value: time.Now()}, }, }, } @@ -120,19 +121,19 @@ func (client *Client) MarkCompleted(jobID string) error { // MarkFailed marks a job as failed, meaning it should be retried. func (client *Client) MarkFailed(jobID string, runAfter time.Time, attempts int, reason string) error { filter := bson.D{ - {"id", jobID}, + {Key: "id", Value: jobID}, } update := bson.D{ - {"$set", - bson.D{ - {"status", model.JobStatusFailed}, - {"finishedAt", time.Now()}, - {"attempts", attempts}, - {"runAfter", runAfter}, + {Key: "$set", + Value: bson.D{ + {Key: "status", Value: model.JobStatusFailed}, + {Key: "finishedAt", Value: time.Now()}, + {Key: "attempts", Value: attempts}, + {Key: "runAfter", Value: runAfter}, }, }, - {"$push", - bson.D{{"errorLogs", reason}}, + {Key: "$push", + Value: bson.D{{Key: "errorLogs", Value: reason}}, }, } @@ -147,17 +148,17 @@ func (client *Client) MarkFailed(jobID string, runAfter time.Time, attempts int, // MarkTerminated marks a job as terminated, meaning it should not be retried. func (client *Client) MarkTerminated(jobID string, reason string) error { filter := bson.D{ - {"id", jobID}, + {Key: "id", Value: jobID}, } update := bson.D{ - {"$set", - bson.D{ - {"status", model.JobStatusTerminated}, - {"finishedAt", time.Now()}, + {Key: "$set", + Value: bson.D{ + {Key: "status", Value: model.JobStatusTerminated}, + {Key: "finishedAt", Value: time.Now()}, }, }, - {"$push", - bson.D{{"errorLogs", reason}}, + {Key: "$push", + Value: bson.D{{Key: "errorLogs", Value: reason}}, }, } @@ -172,8 +173,8 @@ func (client *Client) MarkTerminated(jobID string, reason string) error { // ResetRunning resets all running jobs to pending. // This is used when the application is restarted to prevent jobs from being stuck in running state. func (client *Client) ResetRunning() error { - filter := bson.D{{"status", model.JobStatusRunning}} - update := bson.D{{"$set", bson.D{{"status", model.JobStatusPending}}}} + filter := bson.D{{Key: "status", Value: model.JobStatusRunning}} + update := bson.D{{Key: "$set", Value: bson.D{{Key: "status", Value: model.JobStatusPending}}}} _, err := client.Collection.UpdateMany(context.Background(), filter, update) if err != nil { diff --git a/pkg/db/resources/notification_repo/client.go b/pkg/db/resources/notification_repo/client.go index a2377c99..35f95eb1 100644 --- a/pkg/db/resources/notification_repo/client.go +++ b/pkg/db/resources/notification_repo/client.go @@ -40,7 +40,7 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // WithUserID adds a filter to the client to only include notifications with the given user ID. func (client *Client) WithUserID(ownerID string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"userId", ownerID}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "userId", Value: ownerID}}) client.RestrictUserID = &ownerID return client @@ -48,14 +48,14 @@ func (client *Client) WithUserID(ownerID string) *Client { // WithType adds a filter to the client to only include notifications with the given type. func (client *Client) WithType(notificationType string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"type", notificationType}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "type", Value: notificationType}}) return client } // FilterContent adds a filter to the client to only include notifications with the given content. func (client *Client) FilterContent(contentName string, filter interface{}) *Client { - client.AddExtraFilter(bson.D{{"content." + contentName, filter}}) + client.AddExtraFilter(bson.D{{Key: "content." + contentName, Value: filter}}) return client } diff --git a/pkg/db/resources/notification_repo/db.go b/pkg/db/resources/notification_repo/db.go index 0a4ab06f..c6942381 100644 --- a/pkg/db/resources/notification_repo/db.go +++ b/pkg/db/resources/notification_repo/db.go @@ -3,9 +3,10 @@ package notification_repo import ( "context" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "go.mongodb.org/mongo-driver/bson" - "time" ) func (client *Client) Create(id string, userID string, params *model.NotificationCreateParams) (*model.Notification, error) { @@ -29,17 +30,17 @@ func (client *Client) Create(id string, userID string, params *model.Notificatio } func (client *Client) MarkCompletedByID(id string) error { - return client.SetWithBsonByID(id, bson.D{{"completedAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "completedAt", Value: time.Now()}}) } func (client *Client) MarkReadByID(id string) error { - return client.SetWithBsonByID(id, bson.D{{"readAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "readAt", Value: time.Now()}}) } func (client *Client) MarkToastedByID(id string) error { - return client.SetWithBsonByID(id, bson.D{{"toastedAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "toastedAt", Value: time.Now()}}) } func (client *Client) MarkReadAndCompleted() error { - return client.SetWithBSON(bson.D{{"readAt", time.Now()}, {"completedAt", time.Now()}}) + return client.SetWithBSON(bson.D{{Key: "readAt", Value: time.Now()}, {Key: "completedAt", Value: time.Now()}}) } diff --git a/pkg/db/resources/resource_migration_repo/client.go b/pkg/db/resources/resource_migration_repo/client.go index ccb95b6c..3c400621 100644 --- a/pkg/db/resources/resource_migration_repo/client.go +++ b/pkg/db/resources/resource_migration_repo/client.go @@ -31,42 +31,42 @@ func (c *Client) WithPagination(page, pageSize int) *Client { // WithType adds a filter to the client to only include resource migrations with the given type. func (c *Client) WithType(migrationType string) *Client { - c.ResourceClient.AddExtraFilter(bson.D{{"type", migrationType}}) + c.ResourceClient.AddExtraFilter(bson.D{{Key: "type", Value: migrationType}}) return c } // WithResourceType adds a filter to the client to only include resource migrations with the given resource type. func (c *Client) WithResourceType(resourceType string) *Client { - c.ResourceClient.AddExtraFilter(bson.D{{"resourceType", resourceType}}) + c.ResourceClient.AddExtraFilter(bson.D{{Key: "resourceType", Value: resourceType}}) return c } // WithResourceID adds a filter to the client to only include resource migrations with the given resource ID. func (c *Client) WithResourceID(resourceID string) *Client { - c.ResourceClient.AddExtraFilter(bson.D{{"resourceId", resourceID}}) + c.ResourceClient.AddExtraFilter(bson.D{{Key: "resourceId", Value: resourceID}}) return c } // WithUserID adds a filter to the client to only include resource migrations with the given user ID. func (c *Client) WithUserID(userID string) *Client { - c.ResourceClient.AddExtraFilter(bson.D{{"userId", userID}}) + c.ResourceClient.AddExtraFilter(bson.D{{Key: "userId", Value: userID}}) return c } // WithStatus adds a filter to the client to only include resource migrations with the given status. func (c *Client) WithStatus(status string) *Client { - c.ResourceClient.AddExtraFilter(bson.D{{"status", status}}) + c.ResourceClient.AddExtraFilter(bson.D{{Key: "status", Value: status}}) return c } // WithCode adds a filter to the client to only include resource migrations with the given code. func (c *Client) WithCode(code string) *Client { - c.ResourceClient.AddExtraFilter(bson.D{{"code", code}}) + c.ResourceClient.AddExtraFilter(bson.D{{Key: "code", Value: code}}) return c } diff --git a/pkg/db/resources/resource_migration_repo/db.go b/pkg/db/resources/resource_migration_repo/db.go index 6d730a01..d8b8660f 100644 --- a/pkg/db/resources/resource_migration_repo/db.go +++ b/pkg/db/resources/resource_migration_repo/db.go @@ -2,10 +2,11 @@ package resource_migration_repo import ( "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" - "time" ) func (c *Client) Create(id, userID, resourceID, migrationType, resourceType string, code *string, status string, params interface{}) (*model.ResourceMigration, error) { @@ -38,7 +39,7 @@ func (c *Client) Create(id, userID, resourceID, migrationType, resourceType stri return nil, fmt.Errorf("bad migration type %s", migrationType) } - err := c.CreateIfUnique(id, migration, bson.D{{"resourceId", resourceID}}) + err := c.CreateIfUnique(id, migration, bson.D{{Key: "resourceId", Value: resourceID}}) if err != nil { return nil, fmt.Errorf("failed to create migration. details: %w", err) } diff --git a/pkg/db/resources/sm_repo/client.go b/pkg/db/resources/sm_repo/client.go index fbb101a5..cce181f0 100644 --- a/pkg/db/resources/sm_repo/client.go +++ b/pkg/db/resources/sm_repo/client.go @@ -48,7 +48,7 @@ func (client *Client) IncludeDeletedResources() *Client { // WithOwnerID adds a filter to the client to only include storage managers with the given owner ID. func (client *Client) WithOwnerID(ownerID string) *Client { - filter := bson.D{{"ownerId", ownerID}} + filter := bson.D{{Key: "ownerId", Value: ownerID}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -70,7 +70,7 @@ func (client *Client) WithActivities(activities ...string) *Client { } filter := bson.D{{ - "$or", orFilter, + Key: "$or", Value: orFilter, }} client.ResourceClient.AddExtraFilter(filter) @@ -82,7 +82,7 @@ func (client *Client) WithActivities(activities ...string) *Client { // WithNoActivities adds a filter to the client to only include storage managers without any activities. func (client *Client) WithNoActivities() *Client { filter := bson.D{{ - "activities", bson.M{ + Key: "activities", Value: bson.M{ "$gte": bson.M{}, }, }} @@ -95,7 +95,7 @@ func (client *Client) WithNoActivities() *Client { // WithZone adds a filter to the client to only include storage managers with the given zone. func (client *Client) WithZone(zone string) *Client { - filter := bson.D{{"zone", zone}} + filter := bson.D{{Key: "zone", Value: zone}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) diff --git a/pkg/db/resources/sm_repo/db.go b/pkg/db/resources/sm_repo/db.go index 04234b29..29c1499b 100644 --- a/pkg/db/resources/sm_repo/db.go +++ b/pkg/db/resources/sm_repo/db.go @@ -4,15 +4,16 @@ import ( "context" "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" - "time" ) var ( - // AlreadyExistsErr is returned when a storage manager already exists for a user. - AlreadyExistsErr = fmt.Errorf("storage manager already exists for user") + // ErrAlreadyExists is returned when a storage manager already exists for a user. + ErrAlreadyExists = fmt.Errorf("storage manager already exists for user") ) // Create creates a new storage manager. @@ -28,10 +29,10 @@ func (client *Client) Create(id, ownerID string, params *model.SmCreateParams) ( Subsystems: model.SmSubsystems{}, } - err := client.CreateIfUnique(id, sm, bson.D{{"ownerId", ownerID}}) + err := client.CreateIfUnique(id, sm, bson.D{{Key: "ownerId", Value: ownerID}}) if err != nil { - if errors.Is(err, db.UniqueConstraintErr) { - return nil, AlreadyExistsErr + if errors.Is(err, db.ErrUniqueConstraint) { + return nil, ErrAlreadyExists } else { return nil, err } @@ -48,7 +49,7 @@ func (client *Client) Create(id, ownerID string, params *model.SmCreateParams) ( // GetURL returns the URL of the storage manager. // It uses projection to only fetch the URL. func (client *Client) GetURL(externalPort *int) (*string, error) { - sm, err := client.GetWithFilterAndProjection(bson.D{}, bson.D{{"ownerId", 1}, {"subsystems.k8s.ingressMap", 1}}) + sm, err := client.GetWithFilterAndProjection(bson.D{}, bson.D{{Key: "ownerId", Value: 1}, {Key: "subsystems.k8s.ingressMap", Value: 1}}) if err != nil { return nil, err } @@ -64,23 +65,23 @@ func (client *Client) GetURL(externalPort *int) (*string, error) { // It prepends the key with `subsystems` and unsets it. func (client *Client) DeleteSubsystem(id, key string) error { subsystemKey := fmt.Sprintf("subsystems.%s", key) - return client.UpdateWithBsonByID(id, bson.D{{"$unset", bson.D{{subsystemKey, ""}}}}) + return client.UpdateWithBsonByID(id, bson.D{{Key: "$unset", Value: bson.D{{Key: subsystemKey, Value: ""}}}}) } // SetSubsystem sets a subsystem in a storage manager. // It prepends the key with `subsystems` and sets it. func (client *Client) SetSubsystem(id, key string, update interface{}) error { subsystemKey := fmt.Sprintf("subsystems.%s", key) - return client.SetWithBsonByID(id, bson.D{{subsystemKey, update}}) + return client.SetWithBsonByID(id, bson.D{{Key: subsystemKey, Value: update}}) } // MarkRepaired marks a storage manager as repaired. // It sets RepairedAt and unsets the repairing activity. func (client *Client) MarkRepaired(id string) error { - filter := bson.D{{"id", id}} + filter := bson.D{{Key: "id", Value: id}} update := bson.D{ - {"$set", bson.D{{"repairedAt", time.Now()}}}, - {"$unset", bson.D{{"activities.repairing", ""}}}, + {Key: "$set", Value: bson.D{{Key: "repairedAt", Value: time.Now()}}}, + {Key: "$unset", Value: bson.D{{Key: "activities.repairing", Value: ""}}}, } _, err := client.ResourceClient.Collection.UpdateOne(context.TODO(), filter, update) diff --git a/pkg/db/resources/team_repo/client.go b/pkg/db/resources/team_repo/client.go index eab336c7..ead8a75c 100644 --- a/pkg/db/resources/team_repo/client.go +++ b/pkg/db/resources/team_repo/client.go @@ -1,11 +1,12 @@ package team_repo import ( + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" - "time" ) // Client is used to manage teams in the database. @@ -35,9 +36,9 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // WithUserID adds a filter to the client to only include teams with the given user ID. func (client *Client) WithUserID(userID string) *Client { - client.AddExtraFilter(bson.D{{"$or", bson.A{ - bson.D{{"ownerId", userID}}, - bson.D{{"memberMap." + userID, bson.D{{"$exists", true}}}}, + client.AddExtraFilter(bson.D{{Key: "$or", Value: bson.A{ + bson.D{{Key: "ownerId", Value: userID}}, + bson.D{{Key: "memberMap." + userID, Value: bson.D{{Key: "$exists", Value: true}}}}, }}}) return client @@ -45,21 +46,21 @@ func (client *Client) WithUserID(userID string) *Client { // WithOwnerID adds a filter to the client to only include teams with the given owner ID. func (client *Client) WithOwnerID(ownerID string) *Client { - client.AddExtraFilter(bson.D{{"ownerId", ownerID}}) + client.AddExtraFilter(bson.D{{Key: "ownerId", Value: ownerID}}) return client } // WithResourceID adds a filter to the client to only include teams with the given model ID. func (client *Client) WithResourceID(resourceID string) *Client { - client.AddExtraFilter(bson.D{{"resourceMap." + resourceID, bson.D{{"$exists", true}}}}) + client.AddExtraFilter(bson.D{{Key: "resourceMap." + resourceID, Value: bson.D{{Key: "$exists", Value: true}}}}) return client } // WithNameRegex adds a filter to the client to only include teams with a name matching the given regex. func (client *Client) WithNameRegex(name string) *Client { - filter := bson.D{{"name", bson.D{{"$regex", name}}}} + filter := bson.D{{Key: "name", Value: bson.D{{Key: "$regex", Value: name}}}} client.ResourceClient.AddExtraFilter(filter) return client @@ -67,7 +68,7 @@ func (client *Client) WithNameRegex(name string) *Client { // OlderThan adds a filter to the client to only include teams older than the given timestamp. func (client *Client) OlderThan(timestamp time.Time) *Client { - filter := bson.D{{"createdAt", bson.D{{"$lt", timestamp}}}} + filter := bson.D{{Key: "createdAt", Value: bson.D{{Key: "$lt", Value: timestamp}}}} client.ResourceClient.AddExtraFilter(filter) return client diff --git a/pkg/db/resources/team_repo/db.go b/pkg/db/resources/team_repo/db.go index 9ca48a8e..b65963c2 100644 --- a/pkg/db/resources/team_repo/db.go +++ b/pkg/db/resources/team_repo/db.go @@ -3,14 +3,15 @@ package team_repo import ( "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "go.mongodb.org/mongo-driver/bson" - "time" ) var ( - NameTakenErr = fmt.Errorf("team name taken") + ErrNameTaken = fmt.Errorf("team name taken") ) // Create creates a new team. @@ -25,10 +26,10 @@ func (client *Client) Create(id, ownerID string, params *model.TeamCreateParams) MemberMap: params.MemberMap, } - err := client.CreateIfUnique(id, team, bson.D{{"name", params.Name}}) + err := client.CreateIfUnique(id, team, bson.D{{Key: "name", Value: params.Name}}) if err != nil { - if errors.Is(err, db.UniqueConstraintErr) { - return nil, NameTakenErr + if errors.Is(err, db.ErrUniqueConstraint) { + return nil, ErrNameTaken } return nil, err } @@ -42,7 +43,7 @@ func (client *Client) Create(id, ownerID string, params *model.TeamCreateParams) } func (client *Client) ListMemberIDs(ids ...string) ([]string, error) { - teams, err := client.ListWithFilterAndProjection(bson.D{{"id", bson.D{{"$in", ids}}}}, bson.D{{"memberMap", 1}}) + teams, err := client.ListWithFilterAndProjection(bson.D{{Key: "id", Value: bson.D{{Key: "$in", Value: ids}}}}, bson.D{{Key: "memberMap", Value: 1}}) if err != nil { return nil, err } @@ -66,7 +67,7 @@ func (client *Client) ListMemberIDs(ids ...string) ([]string, error) { func (client *Client) UpdateWithParams(id string, params *model.TeamUpdateParams) error { updateData := bson.D{ - {"updatedAt", time.Now()}, + {Key: "updatedAt", Value: time.Now()}, } db.AddIfNotNil(&updateData, "name", params.Name) @@ -83,7 +84,7 @@ func (client *Client) UpdateWithParams(id string, params *model.TeamUpdateParams func (client *Client) UpdateMember(id string, memberID string, member *model.TeamMember) error { updateData := bson.D{ - {"updatedAt", time.Now()}, + {Key: "updatedAt", Value: time.Now()}, } db.AddIfNotNil(&updateData, "memberMap."+memberID, member) diff --git a/pkg/db/resources/user_repo/client.go b/pkg/db/resources/user_repo/client.go index bd005d61..51be2603 100644 --- a/pkg/db/resources/user_repo/client.go +++ b/pkg/db/resources/user_repo/client.go @@ -1,11 +1,12 @@ package user_repo import ( + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "go.mongodb.org/mongo-driver/bson" - "time" ) // Client is used to manage users in the database. @@ -46,17 +47,17 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // LastAuthenticatedAfter filters the users to only those who have authenticated after the given time. func (client *Client) LastAuthenticatedAfter(lastAuthenticatedAt time.Time) *Client { - client.AddExtraFilter(bson.D{{"lastAuthenticatedAt", bson.D{{"$gt", lastAuthenticatedAt}}}}) + client.AddExtraFilter(bson.D{{Key: "lastAuthenticatedAt", Value: bson.D{{Key: "$gt", Value: lastAuthenticatedAt}}}}) return client } // WithApiKey filters the users to only those with the given API key. func (client *Client) WithApiKey(apiKey string) *Client { - client.AddExtraFilter(bson.D{{"apiKeys", bson.D{{"$elemMatch", - bson.D{ - {"key", apiKey}, - {"expiresAt", bson.D{{"$gt", time.Now()}}}, + client.AddExtraFilter(bson.D{{Key: "apiKeys", Value: bson.D{{Key: "$elemMatch", + Value: bson.D{ + {Key: "key", Value: apiKey}, + {Key: "expiresAt", Value: bson.D{{Key: "$gt", Value: time.Now()}}}, }, }}}}) diff --git a/pkg/db/resources/user_repo/db.go b/pkg/db/resources/user_repo/db.go index 2828e00f..3755a601 100644 --- a/pkg/db/resources/user_repo/db.go +++ b/pkg/db/resources/user_repo/db.go @@ -3,11 +3,12 @@ package user_repo import ( "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" rErrors "github.com/kthcloud/go-deploy/pkg/db/resources/errors" "go.mongodb.org/mongo-driver/bson" - "time" ) // Synchronize creates a new user or updates an existing user. @@ -27,13 +28,13 @@ func (client *Client) Synchronize(id string, params *model.UserSynchronizeParams if current != nil { // Update the user update := bson.D{ - {"username", params.Username}, - {"firstName", params.FirstName}, - {"lastName", params.LastName}, - {"email", params.Email}, - {"effectiveRole", params.EffectiveRole}, - {"isAdmin", params.IsAdmin}, - {"lastAuthenticatedAt", time.Now()}, + {Key: "username", Value: params.Username}, + {Key: "firstName", Value: params.FirstName}, + {Key: "lastName", Value: params.LastName}, + {Key: "email", Value: params.Email}, + {Key: "effectiveRole", Value: params.EffectiveRole}, + {Key: "isAdmin", Value: params.IsAdmin}, + {Key: "lastAuthenticatedAt", Value: time.Now()}, } err = client.SetWithBsonByID(id, update) @@ -55,10 +56,10 @@ func (client *Client) Synchronize(id string, params *model.UserSynchronizeParams EffectiveRole: *params.EffectiveRole, PublicKeys: []model.PublicKey{}, LastAuthenticatedAt: time.Now(), - }, bson.D{{"id", id}}) + }, bson.D{{Key: "id", Value: id}}) if err != nil { - if errors.Is(err, db.UniqueConstraintErr) { + if errors.Is(err, db.ErrUniqueConstraint) { return nil, rErrors.NonUniqueFieldErr } @@ -70,7 +71,7 @@ func (client *Client) Synchronize(id string, params *model.UserSynchronizeParams // GetEmail returns the email for the given user ID. func (client *Client) GetEmail(id string) (string, error) { - user, err := client.GetWithFilterAndProjection(bson.D{{"id", id}}, bson.D{{"email", 1}}) + user, err := client.GetWithFilterAndProjection(bson.D{{Key: "id", Value: id}}, bson.D{{Key: "email", Value: 1}}) if err != nil { return "", err } @@ -80,7 +81,7 @@ func (client *Client) GetEmail(id string) (string, error) { // ListEmails returns a list of emails for the given user IDs. func (client *Client) ListEmails(ids ...string) (map[string]string, error) { - users, err := client.ListWithFilterAndProjection(bson.D{{"id", bson.D{{"$in", ids}}}}, bson.D{{"id", 1}, {"email", 1}}) + users, err := client.ListWithFilterAndProjection(bson.D{{Key: "id", Value: bson.D{{Key: "$in", Value: ids}}}}, bson.D{{Key: "id", Value: 1}, {Key: "email", Value: 1}}) if err != nil { return nil, err } @@ -116,8 +117,8 @@ func (client *Client) UpdateWithParams(id string, params *model.UserUpdateParams // SetGravatar updates the gravatar URL for the user. func (client *Client) SetGravatar(id string, url string) error { update := bson.D{ - {"gravatar.url", url}, - {"gravatar.fetchedAt", time.Now()}, + {Key: "gravatar.url", Value: url}, + {Key: "gravatar.fetchedAt", Value: time.Now()}, } err := client.SetWithBsonByID(id, update) @@ -131,8 +132,8 @@ func (client *Client) SetGravatar(id string, url string) error { // UnsetGravatar removes the gravatar URL for the user. func (client *Client) UnsetGravatar(id string) error { update := bson.D{ - {"$unset", bson.D{{"gravatar.url", ""}}}, - {"$set", bson.D{{"gravatar.fetchedAt", time.Now()}}}, + {Key: "$unset", Value: bson.D{{Key: "gravatar.url", Value: ""}}}, + {Key: "$set", Value: bson.D{{Key: "gravatar.fetchedAt", Value: time.Now()}}}, } err := client.UpdateWithBsonByID(id, update) diff --git a/pkg/db/resources/vm_port_repo/client.go b/pkg/db/resources/vm_port_repo/client.go index 52efea14..693f6fc8 100644 --- a/pkg/db/resources/vm_port_repo/client.go +++ b/pkg/db/resources/vm_port_repo/client.go @@ -39,16 +39,16 @@ func (client *Client) WithPagination(page, pageSize int) *Client { // WithZone adds a filter to the client to only return VM ports in the given zone. func (client *Client) WithZone(zone string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"zone", zone}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "zone", Value: zone}}) return client } // ExcludePortRange adds a filter to the client to exclude VM ports in the given range. func (client *Client) ExcludePortRange(start, end int) *Client { - filter := bson.D{{"$or", bson.A{ - bson.D{{"publicPort", bson.D{{"$lt", start}}}}, - bson.D{{"publicPort", bson.D{{"$gte", end}}}}, + filter := bson.D{{Key: "$or", Value: bson.A{ + bson.D{{Key: "publicPort", Value: bson.D{{Key: "$lt", Value: start}}}}, + bson.D{{Key: "publicPort", Value: bson.D{{Key: "$gte", Value: end}}}}, }}} client.ResourceClient.AddExtraFilter(filter) @@ -58,15 +58,15 @@ func (client *Client) ExcludePortRange(start, end int) *Client { // IncludePortRange adds a filter to the client to only return VM ports in the given range. func (client *Client) IncludePortRange(start, end int) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"publicPort", bson.D{{"$gte", start}}}}) - client.ResourceClient.AddExtraFilter(bson.D{{"publicPort", bson.D{{"$lt", end}}}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "publicPort", Value: bson.D{{Key: "$gte", Value: start}}}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "publicPort", Value: bson.D{{Key: "$lt", Value: end}}}}) return client } // WithVmID adds a filter to the client to only return VM ports for the given VM. func (client *Client) WithVmID(vmID string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"lease.vmId", vmID}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "lease.vmId", Value: vmID}}) return client } diff --git a/pkg/db/resources/vm_port_repo/db.go b/pkg/db/resources/vm_port_repo/db.go index e843b310..e7b28378 100644 --- a/pkg/db/resources/vm_port_repo/db.go +++ b/pkg/db/resources/vm_port_repo/db.go @@ -3,6 +3,7 @@ package vm_port_repo import ( "context" "errors" + "github.com/kthcloud/go-deploy/models/model" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -10,11 +11,11 @@ import ( ) var ( - // PortNotFoundErr is returned when a port is not found. - PortNotFoundErr = errors.New("port not found") - // NoPortsAvailableErr is returned when no ports are available. + // ErrPortNotFound is returned when a port is not found. + ErrPortNotFound = errors.New("port not found") + // ErrNoPortsAvailable is returned when no ports are available. // This is likely due to the port range being full. - NoPortsAvailableErr = errors.New("port not found") + ErrNoPortsAvailable = errors.New("port not found") ) // CreateIfNotExists creates the given port range if it does not already exist. @@ -48,12 +49,12 @@ func (client *Client) CreateIfNotExists(publicPortStart, publicPortEnd int, zone // Lease leases a port for the given VM. func (client *Client) Lease(publicPort, privatePort int, vmID, zone string) (*model.VmPort, error) { filter := bson.D{ - {"publicPort", publicPort}, - {"zone", zone}, - {"lease", nil}, + {Key: "publicPort", Value: publicPort}, + {Key: "zone", Value: zone}, + {Key: "lease", Value: nil}, } - update := bson.D{{"$set", bson.D{{"lease", model.VmPortLease{ + update := bson.D{{Key: "$set", Value: bson.D{{Key: "lease", Value: model.VmPortLease{ VmID: vmID, PrivatePort: privatePort, }}}}} @@ -61,7 +62,7 @@ func (client *Client) Lease(publicPort, privatePort int, vmID, zone string) (*mo res := client.Collection.FindOneAndUpdate(context.Background(), filter, update) if res.Err() != nil { if errors.Is(res.Err(), mongo.ErrNoDocuments) { - return nil, PortNotFoundErr + return nil, ErrPortNotFound } return nil, res.Err() @@ -80,8 +81,8 @@ func (client *Client) Lease(publicPort, privatePort int, vmID, zone string) (*mo func (client *Client) GetOrLeaseAny(privatePort int, vmID, zone string) (*model.VmPort, error) { // First check if the lease already exists filter := bson.D{ - {"lease.vmId", vmID}, - {"lease.privatePort", privatePort}, + {Key: "lease.vmId", Value: vmID}, + {Key: "lease.privatePort", Value: privatePort}, } vmPort, err := client.GetWithFilterAndProjection(filter, nil) @@ -95,14 +96,14 @@ func (client *Client) GetOrLeaseAny(privatePort int, vmID, zone string) (*model. // Fetch a port that is not leased filter = bson.D{ - {"zone", zone}, - {"lease", nil}, + {Key: "zone", Value: zone}, + {Key: "lease", Value: nil}, } update := bson.D{ { - "$set", bson.D{ - {"lease", model.VmPortLease{ + Key: "$set", Value: bson.D{ + {Key: "lease", Value: model.VmPortLease{ VmID: vmID, PrivatePort: privatePort, }}, @@ -113,7 +114,7 @@ func (client *Client) GetOrLeaseAny(privatePort int, vmID, zone string) (*model. res := client.Collection.FindOneAndUpdate(context.Background(), filter, update, options.FindOneAndUpdate().SetReturnDocument(options.After)) if res.Err() != nil { if errors.Is(res.Err(), mongo.ErrNoDocuments) { - return nil, NoPortsAvailableErr + return nil, ErrNoPortsAvailable } return nil, res.Err() @@ -131,13 +132,13 @@ func (client *Client) GetOrLeaseAny(privatePort int, vmID, zone string) (*model. // ReleaseAll releases all ports leased by the given VM. func (client *Client) ReleaseAll(vmID string) error { filter := bson.D{ - {"lease.vmId", vmID}, + {Key: "lease.vmId", Value: vmID}, } update := bson.D{ { - "$set", bson.D{ - {"lease", nil}, + Key: "$set", Value: bson.D{ + {Key: "lease", Value: nil}, }, }, } @@ -154,8 +155,8 @@ func (client *Client) ReleaseAll(vmID string) error { // This removes the port from the database entirely. func (client *Client) Erase(publicPort int, zone string) error { filter := bson.D{ - {"publicPort", publicPort}, - {"zone", zone}, + {Key: "publicPort", Value: publicPort}, + {Key: "zone", Value: zone}, } _, err := client.Collection.DeleteOne(context.TODO(), filter) diff --git a/pkg/db/resources/vm_repo/client.go b/pkg/db/resources/vm_repo/client.go index 625c2ec8..fadf435c 100644 --- a/pkg/db/resources/vm_repo/client.go +++ b/pkg/db/resources/vm_repo/client.go @@ -1,13 +1,14 @@ package vm_repo import ( + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/db/resources/base_clients" "github.com/kthcloud/go-deploy/service/utils" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "time" ) // Client is used to manage VMs in the database. @@ -43,7 +44,7 @@ func New(version ...string) *Client { // WithVersion adds a filter to the client to only return VMs with the given version. func (client *Client) WithVersion(version string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"version", version}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "version", Value: version}}) client.ActivityResourceClient.ExtraFilter = client.ResourceClient.ExtraFilter return client @@ -73,7 +74,7 @@ func (client *Client) IncludeDeletedResources() *Client { // WithOwner adds a filter to the client to only return VMs owned by the given ownerID. func (client *Client) WithOwner(ownerID string) *Client { - client.ResourceClient.AddExtraFilter(bson.D{{"ownerId", ownerID}}) + client.ResourceClient.AddExtraFilter(bson.D{{Key: "ownerId", Value: ownerID}}) client.ActivityResourceClient.ExtraFilter = client.ResourceClient.ExtraFilter client.RestrictUserID = &ownerID @@ -93,7 +94,7 @@ func (client *Client) WithActivities(activities ...string) *Client { } filter := bson.D{{ - "$or", orFilter, + Key: "$or", Value: orFilter, }} client.ResourceClient.AddExtraFilter(filter) @@ -105,7 +106,7 @@ func (client *Client) WithActivities(activities ...string) *Client { // WithNoActivities adds a filter to the client to only return VMs that have no activities. func (client *Client) WithNoActivities() *Client { filter := bson.D{{ - "activities", bson.M{ + Key: "activities", Value: bson.M{ "$gte": bson.M{}, }, }} @@ -118,7 +119,7 @@ func (client *Client) WithNoActivities() *Client { // WithIDs adds a filter to the client to only return VMs with the given IDs. func (client *Client) WithIDs(ids ...string) *Client { - filter := bson.D{{"id", bson.D{{"$in", ids}}}} + filter := bson.D{{Key: "id", Value: bson.D{{Key: "$in", Value: ids}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -136,7 +137,7 @@ func (client *Client) WithCustomFilter(filter bson.D) *Client { // WithNameRegex adds a filter to the client to only return VMs with names matching the given regex. func (client *Client) WithNameRegex(name string) *Client { - filter := bson.D{{"name", bson.D{{"$regex", name}}}} + filter := bson.D{{Key: "name", Value: bson.D{{Key: "$regex", Value: name}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -146,7 +147,7 @@ func (client *Client) WithNameRegex(name string) *Client { // WithZone adds a filter to the client to only return VMs in the given zone. func (client *Client) WithZone(zone ...string) *Client { - filter := bson.D{{"zone", bson.D{{"$in", zone}}}} + filter := bson.D{{Key: "zone", Value: bson.D{{Key: "$in", Value: zone}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -156,7 +157,7 @@ func (client *Client) WithZone(zone ...string) *Client { // OlderThan adds a filter to the client to only return VMs created before the given timestamp. func (client *Client) OlderThan(timestamp time.Time) *Client { - filter := bson.D{{"createdAt", bson.D{{"$lt", timestamp}}}} + filter := bson.D{{Key: "createdAt", Value: bson.D{{Key: "$lt", Value: timestamp}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) @@ -166,7 +167,7 @@ func (client *Client) OlderThan(timestamp time.Time) *Client { // LastAccessedBefore adds a filter to the client to only return VMs that were last accessed before the given timestamp. func (client *Client) LastAccessedBefore(timestamp time.Time) *Client { - filter := bson.D{{"accessedAt", bson.D{{"$lt", timestamp}}}} + filter := bson.D{{Key: "accessedAt", Value: bson.D{{Key: "$lt", Value: timestamp}}}} client.ResourceClient.AddExtraFilter(filter) client.ActivityResourceClient.AddExtraFilter(filter) diff --git a/pkg/db/resources/vm_repo/db.go b/pkg/db/resources/vm_repo/db.go index cce72fe3..462468d2 100644 --- a/pkg/db/resources/vm_repo/db.go +++ b/pkg/db/resources/vm_repo/db.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "time" + "github.com/google/uuid" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/models/version" @@ -13,7 +15,6 @@ import ( "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "time" ) // Create creates a new VM. @@ -65,7 +66,7 @@ func (client *Client) Create(id, owner string, params *model.VmCreateParams) (*m }, Subsystems: model.Subsystems{}, - Activities: map[string]model.Activity{model.ActivityBeingCreated: {model.ActivityBeingCreated, time.Now()}}, + Activities: map[string]model.Activity{model.ActivityBeingCreated: {Name: model.ActivityBeingCreated, CreatedAt: time.Now()}}, Host: nil, Status: status_codes.GetMsg(status_codes.ResourceCreating), @@ -87,8 +88,30 @@ func (client *Client) Create(id, owner string, params *model.VmCreateParams) (*m // It uses aggregation to do this, so it is not very efficient. func (client *Client) ListWithAnyPendingCustomDomain() ([]model.VM, error) { pipeline := mongo.Pipeline{ - {{"$addFields", bson.D{{"portMapArray", bson.D{{"$objectToArray", "$portMap"}}}}}}, - {{"$match", bson.D{{"portMapArray", bson.D{{"$elemMatch", bson.D{{"v.httpProxy.customDomain.status", bson.D{{"$in", []string{model.CustomDomainStatusPending, model.CustomDomainStatusVerificationFailed}}}}}}}}}}}, + {{Key: "$addFields", + Value: bson.D{{ + Key: "portMapArray", + Value: bson.D{{ + Key: "$objectToArray", + Value: "$portMap", + }}, + }}, + }}, + {{Key: "$match", + Value: bson.D{{ + Key: "portMapArray", + Value: bson.D{{ + Key: "$elemMatch", + Value: bson.D{{ + Key: "v.httpProxy.customDomain.status", + Value: bson.D{{ + Key: "$in", + Value: []string{model.CustomDomainStatusPending, model.CustomDomainStatusVerificationFailed}, + }}, + }}, + }}, + }}, + }}, } cursor, err := client.Collection.Aggregate(context.Background(), pipeline) @@ -132,8 +155,8 @@ func (client *Client) UpdateWithParams(id string, params *model.VmUpdateParams) for _, port := range *params.PortMap { if port.HttpProxy != nil { filter := bson.D{ - {"id", bson.D{{"$ne", id}}}, - {"ports.httpProxy.name", port.HttpProxy.Name}, + {Key: "id", Value: bson.D{{Key: "$ne", Value: id}}}, + {Key: "ports.httpProxy.name", Value: port.HttpProxy.Name}, } existAny, err := client.ResourceClient.ExistsWithFilter(filter) @@ -151,7 +174,7 @@ func (client *Client) UpdateWithParams(id string, params *model.VmUpdateParams) // Updating ports requires some extra love! // (since we delete custom domains by setting them to "") if params.PortMap != nil { - onlyPorts, err := client.GetWithFilterAndProjection(bson.D{{"id", id}}, bson.D{{"portMap", 1}}) + onlyPorts, err := client.GetWithFilterAndProjection(bson.D{{Key: "id", Value: id}}, bson.D{{Key: "portMap", Value: 1}}) if err != nil { return err } @@ -200,8 +223,8 @@ func (client *Client) UpdateWithParams(id string, params *model.VmUpdateParams) err := client.UpdateWithBsonByID(id, bson.D{ - {"$set", setUpdate}, - {"$unset", unsetUpdate}, + {Key: "$set", Value: setUpdate}, + {Key: "$unset", Value: unsetUpdate}, }, ) if err != nil { @@ -218,10 +241,10 @@ func (client *Client) UpdateWithParams(id string, params *model.VmUpdateParams) // GetUsage returns the usage in CPU cores, RAM, disk size and snapshots. func (client *Client) GetUsage() (*model.VmUsage, error) { projection := bson.D{ - {"_id", 0}, - {"id", 1}, - {"name", 1}, - {"specs", 1}, + {Key: "_id", Value: 0}, + {Key: "id", Value: 1}, + {Key: "name", Value: 1}, + {Key: "specs", Value: 1}, } vms, err := client.ListWithFilterAndProjection(bson.D{}, projection) @@ -248,20 +271,20 @@ func (client *Client) GetUsage() (*model.VmUsage, error) { // It prepends the key with `subsystems` and unsets it. func (client *Client) DeleteSubsystem(id, key string) error { subsystemKey := fmt.Sprintf("subsystems.%s", key) - return client.UpdateWithBsonByID(id, bson.D{{"$unset", bson.D{{subsystemKey, ""}}}}) + return client.UpdateWithBsonByID(id, bson.D{{Key: "$unset", Value: bson.D{{Key: subsystemKey, Value: ""}}}}) } // SetSubsystem sets a subsystem in a VM. // It prepends the key with `subsystems` and sets it. func (client *Client) SetSubsystem(id, key string, update interface{}) error { subsystemKey := fmt.Sprintf("subsystems.%s", key) - return client.SetWithBsonByID(id, bson.D{{subsystemKey, update}}) + return client.SetWithBsonByID(id, bson.D{{Key: subsystemKey, Value: update}}) } // UpdateCustomDomainStatus updates the status of a custom domain for a given port. func (client *Client) UpdateCustomDomainStatus(id, portName, status string) error { update := bson.D{ - {"$set", bson.D{{"portMap." + portName + ".httpProxy.customDomain.status", status}}}, + {Key: "$set", Value: bson.D{{Key: "portMap." + portName + ".httpProxy.customDomain.status", Value: status}}}, } return client.UpdateWithBsonByID(id, update) @@ -269,12 +292,12 @@ func (client *Client) UpdateCustomDomainStatus(id, portName, status string) erro // SetStatusByName sets the status of a deployment. func (client *Client) SetStatusByName(name, status string) error { - return client.SetWithBsonByName(name, bson.D{{"status", status}}) + return client.SetWithBsonByName(name, bson.D{{Key: "status", Value: status}}) } // SetCurrentHost sets the current host of a VM. func (client *Client) SetCurrentHost(name string, host *model.VmHost) error { - return client.SetWithBsonByName(name, bson.D{{"host", host}}) + return client.SetWithBsonByName(name, bson.D{{Key: "host", Value: host}}) } // UnsetCurrentHost unsets the current host of a VM. @@ -285,10 +308,10 @@ func (client *Client) UnsetCurrentHost(name string) error { // MarkRepaired marks a VM as repaired. // It sets RepairedAt and unsets the repairing activity. func (client *Client) MarkRepaired(id string) error { - filter := bson.D{{"id", id}} + filter := bson.D{{Key: "id", Value: id}} update := bson.D{ - {"$set", bson.D{{"repairedAt", time.Now()}}}, - {"$unset", bson.D{{"activities.repairing", ""}}}, + {Key: "$set", Value: bson.D{{Key: "repairedAt", Value: time.Now()}}}, + {Key: "$unset", Value: bson.D{{Key: "activities.repairing", Value: ""}}}, } _, err := client.Collection.UpdateOne(context.TODO(), filter, update) @@ -302,10 +325,10 @@ func (client *Client) MarkRepaired(id string) error { // MarkUpdated marks a VM as updated. // It sets UpdatedAt and unsets the updating activity. func (client *Client) MarkUpdated(id string) error { - filter := bson.D{{"id", id}} + filter := bson.D{{Key: "id", Value: id}} update := bson.D{ - {"$set", bson.D{{"updatedAt", time.Now()}}}, - {"$unset", bson.D{{"activities.updating", ""}}}, + {Key: "$set", Value: bson.D{{Key: "updatedAt", Value: time.Now()}}}, + {Key: "$unset", Value: bson.D{{Key: "activities.updating", Value: ""}}}, } _, err := client.Collection.UpdateOne(context.TODO(), filter, update) @@ -318,7 +341,7 @@ func (client *Client) MarkUpdated(id string) error { // MarkAccessed marks a deployment as accessed to the current time. func (client *Client) MarkAccessed(id string) error { - return client.SetWithBsonByID(id, bson.D{{"accessedAt", time.Now()}}) + return client.SetWithBsonByID(id, bson.D{{Key: "accessedAt", Value: time.Now()}}) } // generateCustomDomainSecret generates a random alphanumeric string. diff --git a/pkg/db/resources/worker_status_repo/db.go b/pkg/db/resources/worker_status_repo/db.go index 9a24f2d6..bb7ff5ea 100644 --- a/pkg/db/resources/worker_status_repo/db.go +++ b/pkg/db/resources/worker_status_repo/db.go @@ -2,19 +2,20 @@ package worker_status_repo import ( "context" + "time" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" - "time" ) // CreateOrUpdate creates or updates a worker status. // If the worker status already exists, it will be updated. func (client *Client) CreateOrUpdate(name, status string) error { - filter := bson.D{{"name", name}} - update := bson.D{{"$set", bson.D{ - {"name", name}, - {"status", status}, - {"reportedAt", time.Now()}, + filter := bson.D{{Key: "name", Value: name}} + update := bson.D{{Key: "$set", Value: bson.D{ + {Key: "name", Value: name}, + {Key: "status", Value: status}, + {Key: "reportedAt", Value: time.Now()}, }}} _, err := client.Collection.UpdateOne(context.TODO(), filter, update, options.Update().SetUpsert(true)) @@ -27,7 +28,7 @@ func (client *Client) CreateOrUpdate(name, status string) error { // DeleteStale deletes all worker statuses that have not been updated in the last 24 hours. func (client *Client) DeleteStale() error { - filter := bson.D{{"reportedAt", bson.D{{"$lt", time.Now().Add(-24 * time.Hour)}}}} + filter := bson.D{{Key: "reportedAt", Value: bson.D{{Key: "$lt", Value: time.Now().Add(-24 * time.Hour)}}}} _, err := client.Collection.DeleteMany(context.TODO(), filter) if err != nil { return err diff --git a/pkg/jobs/utils/utils.go b/pkg/jobs/utils/utils.go index 69b2c8d9..9f19e3e8 100644 --- a/pkg/jobs/utils/utils.go +++ b/pkg/jobs/utils/utils.go @@ -3,6 +3,9 @@ package utils import ( "context" "fmt" + "reflect" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" @@ -13,8 +16,6 @@ import ( "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "golang.org/x/exp/slices" - "reflect" - "time" ) // AssertParameters asserts that the job has all the required parameters. @@ -258,9 +259,9 @@ func UpdatingOwner(job *model.Job) (bool, error) { id := job.Args["id"].(string) filter := bson.D{ - {"args.id", id}, - {"type", model.JobUpdateVmOwner}, - {"status", bson.D{{"$nin", []string{model.JobStatusCompleted, model.JobStatusTerminated}}}}, + {Key: "args.id", Value: id}, + {Key: "type", Value: model.JobUpdateVmOwner}, + {Key: "status", Value: bson.D{{Key: "$nin", Value: []string{model.JobStatusCompleted, model.JobStatusTerminated}}}}, } anyUpdatingOwnerJob, err := job_repo.New().AddFilter(filter).ExistsAny() diff --git a/pkg/services/status_update/vm_status_listener.go b/pkg/services/status_update/vm_status_listener.go index ef304016..eceb010f 100644 --- a/pkg/services/status_update/vm_status_listener.go +++ b/pkg/services/status_update/vm_status_listener.go @@ -3,6 +3,7 @@ package status_update import ( "context" "fmt" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/models/version" @@ -26,7 +27,7 @@ func VmStatusListener(ctx context.Context) error { err := k8s_service.New().SetupStatusWatcher(ctx, &z, "vm", func(name string, incomingStatus interface{}) { if status, ok := incomingStatus.(*model.VmStatus); ok { kubeVirtStatus := parseVmStatus(status) - err := vm_repo.New(version.V2).SetWithBsonByName(name, bson.D{{"status", kubeVirtStatus}}) + err := vm_repo.New(version.V2).SetWithBsonByName(name, bson.D{{Key: "status", Value: kubeVirtStatus}}) if err != nil { log.Printf("Failed to update VM status for %s. details: %s", name, err.Error()) return diff --git a/pkg/services/synchronize/fetch_gpu.go b/pkg/services/synchronize/fetch_gpu.go index e4f5ed27..6aa0456a 100644 --- a/pkg/services/synchronize/fetch_gpu.go +++ b/pkg/services/synchronize/fetch_gpu.go @@ -2,6 +2,8 @@ package synchronize import ( "fmt" + "strings" + "github.com/kthcloud/go-deploy/dto/v2/body" configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" @@ -12,7 +14,6 @@ import ( "github.com/kthcloud/go-deploy/service" "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" - "strings" ) // GpuSynchronizer synchronizes the GPUs in the database with the sys-api page. @@ -85,12 +86,12 @@ func synchronizeGPUs(gpuInfo *body.SystemGpuInfo) error { } } else { err = gpu_group_repo.New().WithZone(zone).SetWithBsonByID(group.ID, bson.D{ - {"name", group.Name}, - {"displayName", group.DisplayName}, - {"total", group.Total}, - {"vendor", group.Vendor}, - {"vendorId", group.VendorID}, - {"deviceId", group.DeviceID}, + {Key: "name", Value: group.Name}, + {Key: "displayName", Value: group.DisplayName}, + {Key: "total", Value: group.Total}, + {Key: "vendor", Value: group.Vendor}, + {Key: "vendorId", Value: group.VendorID}, + {Key: "deviceId", Value: group.DeviceID}, }) if err != nil { return err diff --git a/routers/api/v2/snapshot.go b/routers/api/v2/snapshot.go index ae28b62f..b8f868b6 100644 --- a/routers/api/v2/snapshot.go +++ b/routers/api/v2/snapshot.go @@ -1,20 +1,8 @@ package v2 import ( - "errors" - "github.com/gin-gonic/gin" - "github.com/google/uuid" - "github.com/kthcloud/go-deploy/dto/v2/body" - "github.com/kthcloud/go-deploy/dto/v2/query" - "github.com/kthcloud/go-deploy/dto/v2/uri" - "github.com/kthcloud/go-deploy/models/model" - "github.com/kthcloud/go-deploy/models/version" "github.com/kthcloud/go-deploy/pkg/sys" - "github.com/kthcloud/go-deploy/service" - sErrors "github.com/kthcloud/go-deploy/service/errors" - "github.com/kthcloud/go-deploy/service/v2/utils" - "github.com/kthcloud/go-deploy/service/v2/vms/opts" ) // GetSnapshot @@ -37,9 +25,8 @@ func GetSnapshot(c *gin.Context) { // Not yet implemented context.NotImplemented() - return - var requestURI uri.VmSnapshotGet + /*var requestURI uri.VmSnapshotGet if err := context.GinContext.ShouldBindUri(&requestURI); err != nil { context.BindingError(CreateBindingError(err)) return @@ -75,7 +62,7 @@ func GetSnapshot(c *gin.Context) { return } - context.Ok(snapshot.ToDTOv2()) + context.Ok(snapshot.ToDTOv2())*/ } // ListSnapshots @@ -99,9 +86,8 @@ func ListSnapshots(c *gin.Context) { // Not yet implemented context.NotImplemented() - return - var requestQuery query.VmSnapshotList + /*var requestQuery query.VmSnapshotList if err := context.GinContext.ShouldBind(&requestQuery); err != nil { context.BindingError(CreateBindingError(err)) return @@ -131,7 +117,7 @@ func ListSnapshots(c *gin.Context) { dtoSnapshots[i] = snapshot.ToDTOv2() } - context.Ok(dtoSnapshots) + context.Ok(dtoSnapshots)*/ } // CreateSnapshot @@ -153,9 +139,8 @@ func CreateSnapshot(c *gin.Context) { // Not yet implemented context.NotImplemented() - return - var requestURI uri.VmSnapshotCreate + /*var requestURI uri.VmSnapshotCreate if err := context.GinContext.ShouldBindUri(&requestURI); err != nil { context.BindingError(CreateBindingError(err)) return @@ -233,7 +218,7 @@ func CreateSnapshot(c *gin.Context) { context.Ok(body.VmSnapshotCreated{ ID: vm.ID, JobID: jobID, - }) + })*/ } // DeleteSnapshot @@ -256,9 +241,8 @@ func DeleteSnapshot(c *gin.Context) { // Not yet implemented context.NotImplemented() - return - var requestURI uri.VmSnapshotDelete + /*var requestURI uri.VmSnapshotDelete if err := context.GinContext.ShouldBindUri(&requestURI); err != nil { context.BindingError(CreateBindingError(err)) return @@ -309,5 +293,5 @@ func DeleteSnapshot(c *gin.Context) { context.Ok(body.VmSnapshotDeleted{ ID: vm.ID, JobID: jobID, - }) + })*/ } diff --git a/scripts/check-lint.sh b/scripts/check-lint.sh index 91bba1ad..9e2a02a1 100755 --- a/scripts/check-lint.sh +++ b/scripts/check-lint.sh @@ -25,6 +25,10 @@ function check_ineffassign() { command -v ineffassign >/dev/null 2>&1 || { echo -e "${YELLOW}ineffassign is not installed. Installing...${NC}"; go install github.com/gordonklaus/ineffassign@latest; } } +function check_staticcheck() { + command -v staticcheck >/dev/null 2>&1 || { echo -e "${YELLOW}go-staticcheck is not installed. Installing...${NC}"; go install honnef.co/go/tools/cmd/staticcheck@latest; } +} + function run_gofmt() { echo -e "${YELLOW}Running gofmt check...${NC}" # Check for formatting issues @@ -77,6 +81,19 @@ function run_ineffassign() { fi } +function run_staticcheck() { + echo -e "${YELLOW}Running go-staticcheck check...${NC}" + # Run staticcheck to analyze code for potential issues + staticcheck_output=$(staticcheck ./...) + if [ -n "$staticcheck_output" ]; then + echo -e "${RED}go-staticcheck found the following issues:${NC}" + echo "$staticcheck_output" + staticcheck_error=1 + else + echo -e "${GREEN}passed go-staticcheck.${NC}" + fi +} + # Get the git root, to make sure the scripts are run in the correct location git_root=$(get_git_root) @@ -88,21 +105,24 @@ check_gofmt check_go_vet check_go_cyclo check_ineffassign +check_staticcheck # Initialize error flags gofmt_error=0 go_vet_error=0 go_cyclo_error=0 ineffassign_error=0 +staticcheck_error=0 # Execute checks run_gofmt run_go_vet run_go_cyclo run_ineffassign +run_staticcheck # Print a summary and exit with failure if there were any errors -if [ $gofmt_error -eq 1 ] || [ $go_vet_error -eq 1 ] || [ $go_cyclo_error -eq 1 ] || [ $ineffassign_error -eq 1 ]; then +if [ $gofmt_error -eq 1 ] || [ $go_vet_error -eq 1 ] || [ $go_cyclo_error -eq 1 ] || [ $ineffassign_error -eq 1 ] || [ $staticcheck_error -eq 1 ]; then echo -e "${RED}SUMMARY: Please resolve the above issues.${NC}" exit 1 else diff --git a/service/v2/deployments/deployment_service.go b/service/v2/deployments/deployment_service.go index 2b13a6ef..3bafb463 100644 --- a/service/v2/deployments/deployment_service.go +++ b/service/v2/deployments/deployment_service.go @@ -3,6 +3,9 @@ package deployments import ( "errors" "fmt" + "sort" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" @@ -19,8 +22,6 @@ import ( "github.com/kthcloud/go-deploy/utils" "github.com/kthcloud/go-deploy/utils/subsystemutils" "go.mongodb.org/mongo-driver/bson" - "sort" - "time" ) // Get gets an existing deployment. @@ -542,7 +543,7 @@ func (c *Client) Restart(id string) error { CreatedAt: time.Now(), }) - err = deployment_repo.New().SetWithBsonByID(id, bson.D{{"restartedAt", time.Now()}}) + err = deployment_repo.New().SetWithBsonByID(id, bson.D{{Key: "restartedAt", Value: time.Now()}}) if err != nil { return makeError(err) } diff --git a/service/v2/resource_migrations/resource_migration_service.go b/service/v2/resource_migrations/resource_migration_service.go index 8635f39d..ab2e46ba 100644 --- a/service/v2/resource_migrations/resource_migration_service.go +++ b/service/v2/resource_migrations/resource_migration_service.go @@ -3,6 +3,7 @@ package resource_migrations import ( "errors" "fmt" + "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" @@ -143,7 +144,7 @@ func (c *Client) CreateMigrationUpdateOwner(id, userID, resourceID, resourceType rmc := resource_migration_repo.New() resourceMigration, err := rmc.Create(id, userID, resourceID, model.ResourceMigrationTypeUpdateOwner, resourceType, &code, status, params) if err != nil { - if errors.Is(err, db.UniqueConstraintErr) { + if errors.Is(err, db.ErrUniqueConstraint) { return nil, nil, sErrors.ResourceMigrationAlreadyExistsErr } diff --git a/service/v2/sms/sm_service.go b/service/v2/sms/sm_service.go index 8db78c99..cbfdfe7c 100644 --- a/service/v2/sms/sm_service.go +++ b/service/v2/sms/sm_service.go @@ -3,6 +3,10 @@ package sms import ( "errors" "fmt" + "sort" + "strconv" + "strings" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -12,9 +16,6 @@ import ( "github.com/kthcloud/go-deploy/service/utils" "github.com/kthcloud/go-deploy/service/v2/sms/k8s_service" "github.com/kthcloud/go-deploy/service/v2/sms/opts" - "sort" - "strconv" - "strings" ) // Get gets an existing storage manager @@ -79,7 +80,7 @@ func (c *Client) Create(id, userID string, params *model.SmCreateParams) error { _, err := sm_repo.New().Create(id, userID, params) if err != nil { - if errors.Is(err, sm_repo.AlreadyExistsErr) { + if errors.Is(err, sm_repo.ErrAlreadyExists) { return sErrors.SmAlreadyExistsErr } diff --git a/service/v2/teams/team_service.go b/service/v2/teams/team_service.go index 59c25e8a..faca54ca 100644 --- a/service/v2/teams/team_service.go +++ b/service/v2/teams/team_service.go @@ -3,6 +3,8 @@ package teams import ( "errors" "fmt" + "time" + "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" @@ -15,7 +17,6 @@ import ( "github.com/kthcloud/go-deploy/service/v2/teams/opts" "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" - "time" ) // Get gets a team by ID @@ -132,7 +133,7 @@ func (c *Client) Create(id, ownerID string, dtoCreateTeam *body.TeamCreate) (*mo team, err := team_repo.New().Create(id, ownerID, params) if err != nil { - if errors.Is(err, team_repo.NameTakenErr) { + if errors.Is(err, team_repo.ErrNameTaken) { return nil, sErrors.TeamNameTakenErr } @@ -258,7 +259,7 @@ func (c *Client) CleanResource(resourceID string) error { for _, team := range teams { delete(team.GetResourceMap(), resourceID) - err = tmc.UpdateWithBsonByID(team.ID, bson.D{{"$set", bson.D{{"resourceMap", team.ResourceMap}}}}) + err = tmc.UpdateWithBsonByID(team.ID, bson.D{{Key: "$set", Value: bson.D{{Key: "resourceMap", Value: team.ResourceMap}}}}) if err != nil { return err } diff --git a/service/v2/vms/k8s_service/k8s_service.go b/service/v2/vms/k8s_service/k8s_service.go index e1f7300e..f6796001 100644 --- a/service/v2/vms/k8s_service/k8s_service.go +++ b/service/v2/vms/k8s_service/k8s_service.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/models/version" @@ -103,7 +104,7 @@ func (c *Client) Create(id string, params *model.VmCreateParams) error { if port.Port == 0 { vmPort, err := vm_port_repo.New().GetOrLeaseAny(port.TargetPort, vm.ID, vm.Zone) if err != nil { - if errors.Is(err, vm_port_repo.NoPortsAvailableErr) { + if errors.Is(err, vm_port_repo.ErrNoPortsAvailable) { return makeError(sErrors.NoPortsAvailableErr) } @@ -388,7 +389,7 @@ func (c *Client) Repair(id string) error { if port.Port == 0 { vmPort, err := vm_port_repo.New().GetOrLeaseAny(port.TargetPort, vm.ID, vm.Zone) if err != nil { - if errors.Is(err, vm_port_repo.NoPortsAvailableErr) { + if errors.Is(err, vm_port_repo.ErrNoPortsAvailable) { return makeError(sErrors.NoPortsAvailableErr) } diff --git a/service/v2/vms/vm_service.go b/service/v2/vms/vm_service.go index c1ece24e..46b63f77 100644 --- a/service/v2/vms/vm_service.go +++ b/service/v2/vms/vm_service.go @@ -3,6 +3,9 @@ package vms import ( "errors" "fmt" + "sort" + "strings" + "github.com/kthcloud/go-deploy/dto/v2/body" configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" @@ -21,8 +24,6 @@ import ( "github.com/kthcloud/go-deploy/service/v2/vms/opts" "github.com/kthcloud/go-deploy/utils" "go.mongodb.org/mongo-driver/bson" - "sort" - "strings" ) // Get gets an existing VM. @@ -538,8 +539,8 @@ func (c *Client) NameAvailable(name string) (bool, error) { // HttpProxyNameAvailable checks if the given name is available for an HTTP proxy. func (c *Client) HttpProxyNameAvailable(id, name string) (bool, error) { filter := bson.D{ - {"id", bson.D{{"$ne", id}}}, - {"portMap.httpProxy.name", name}, + {Key: "id", Value: bson.D{{Key: "$ne", Value: id}}}, + {Key: "portMap.httpProxy.name", Value: name}, } exists, err := vm_repo.New().WithCustomFilter(filter).ExistsAny() From 6da31c3829fa8f54872388f93c26909dee89ec48 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 18:03:18 +0100 Subject: [PATCH 14/36] Improve go-staticcheck results --- cmd/server.go | 15 +- dto/v2/body/deployment.go | 2 +- pkg/auth/gin_keycloak.go | 10 +- pkg/db/message_queue/client.go | 5 +- pkg/db/migrate/migrate.go | 1 + pkg/db/resources/deployment_repo/db.go | 8 +- pkg/db/resources/errors/errors.go | 4 +- pkg/db/resources/event_repo/client.go | 7 +- pkg/db/resources/gpu_group_repo/db.go | 2 +- pkg/db/resources/gpu_group_repo/errors.go | 4 +- pkg/db/resources/gpu_lease_repo/db.go | 4 +- pkg/db/resources/gpu_lease_repo/errors.go | 8 +- pkg/db/resources/user_repo/db.go | 2 +- pkg/db/resources/vm_repo/db.go | 6 +- pkg/imp/harbor/harbor/client_test.go | 4 +- pkg/intializer/system_services.go | 3 +- pkg/intializer/test.go | 5 +- pkg/jobs/v2/deployment_jobs.go | 15 +- pkg/jobs/v2/sm_jobs.go | 7 +- pkg/jobs/v2/vm_jobs.go | 33 ++-- pkg/services/errors/errors.go | 8 +- pkg/services/logger/pod_logger.go | 11 +- pkg/services/logger/pod_logger_control.go | 8 +- .../system_state_poll/gpu_info_worker.go | 7 +- .../system_state_poll/stats_worker.go | 9 +- .../system_state_poll/status_worker.go | 7 +- pkg/services/workers.go | 23 +-- pkg/subsystems/harbor/common.go | 26 ++- pkg/subsystems/k8s/errors/errors.go | 8 +- pkg/subsystems/k8s/ingress.go | 9 +- pkg/subsystems/k8s/logs.go | 73 ++++---- pkg/subsystems/k8s/manifests.go | 7 +- pkg/subsystems/k8s/pod.go | 7 +- pkg/subsystems/k8s/status.go | 43 +++-- routers/api/v2/api_key.go | 8 +- routers/api/v2/deployment.go | 38 ++--- routers/api/v2/deployment_ci_config.go | 8 +- routers/api/v2/deployment_command.go | 4 +- routers/api/v2/deployment_hook.go | 13 +- routers/api/v2/deployment_logs.go | 6 +- routers/api/v2/discover.go | 2 +- routers/api/v2/errors.go | 36 ++-- routers/api/v2/gpu_group.go | 12 +- routers/api/v2/gpu_lease.go | 36 ++-- routers/api/v2/job.go | 16 +- .../api/v2/middleware/access_gpu_routes.go | 5 +- routers/api/v2/middleware/synchronize_user.go | 13 +- routers/api/v2/notification.go | 18 +- routers/api/v2/register.go | 6 +- routers/api/v2/resource_migration.go | 58 +++---- routers/api/v2/sm.go | 12 +- routers/api/v2/system.go | 6 +- routers/api/v2/team.go | 34 ++-- routers/api/v2/user.go | 20 +-- routers/api/v2/vm.go | 32 ++-- routers/api/v2/vm_action.go | 6 +- routers/api/v2/worker_status.go | 2 +- routers/api/v2/zone.go | 4 +- routers/api/validators/validators.go | 12 +- routers/router.go | 4 +- scripts/check-lint.sh | 2 +- service/errors/errors.go | 160 +++++++++--------- service/v2/deployments/ci_config_service.go | 7 +- service/v2/deployments/deployment_service.go | 34 ++-- .../v2/deployments/harbor_service/client.go | 6 +- service/v2/deployments/k8s_service/client.go | 10 +- .../v2/deployments/k8s_service/k8s_service.go | 23 +-- service/v2/deployments/logs_service.go | 9 +- .../v2/deployments/resources/k8s_generator.go | 15 +- service/v2/jobs/job_service.go | 2 +- .../v2/notifications/notification_service.go | 2 +- .../resource_migration_service.go | 36 ++-- service/v2/sms/k8s_service/client.go | 8 +- service/v2/sms/k8s_service/k8s_service.go | 15 +- service/v2/sms/sm_service.go | 2 +- service/v2/system/registration_service.go | 6 +- service/v2/teams/team_service.go | 8 +- service/v2/users/api_key/api_key.go | 11 +- service/v2/users/user_service.go | 9 +- .../v2/vms/gpu_leases/gpu_lease_service.go | 30 ++-- service/v2/vms/k8s_service/client.go | 11 +- service/v2/vms/k8s_service/k8s_service.go | 30 ++-- service/v2/vms/vm_service.go | 18 +- test/acc/subsystems/k8s/helpers.go | 5 +- test/e2e/common.go | 12 +- test/e2e/v2/team_utils.go | 9 +- utils/utils.go | 10 +- 87 files changed, 658 insertions(+), 634 deletions(-) diff --git a/cmd/server.go b/cmd/server.go index 93cc4bd0..f90af600 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -5,19 +5,20 @@ import ( "errors" argFlag "flag" "fmt" + "net/http" + "os" + "time" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/models/mode" "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/db" - "github.com/kthcloud/go-deploy/pkg/db/migrate" + migrator "github.com/kthcloud/go-deploy/pkg/db/migrate" "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" "github.com/kthcloud/go-deploy/pkg/intializer" "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/pkg/metrics" "github.com/kthcloud/go-deploy/routers" - "net/http" - "os" - "time" ) type Options struct { @@ -128,10 +129,8 @@ func (app *App) Stop() { log.Fatalln(fmt.Errorf("failed to shutdown server. details: %w", err)) } - select { - case <-ctx.Done(): - log.Println("Saiting for http server to shutdown...") - } + <-ctx.Done() + log.Println("Saiting for http server to shutdown...") } shutdown() diff --git a/dto/v2/body/deployment.go b/dto/v2/body/deployment.go index 7f90dd74..a5aa0ff7 100644 --- a/dto/v2/body/deployment.go +++ b/dto/v2/body/deployment.go @@ -90,7 +90,7 @@ type DeploymentUpdate struct { // Deprecated: Use Visibility instead. Private *bool `json:"private,omitempty" bson:"private,omitempty" binding:"omitempty,boolean"` - Image *string `json:"image,omitempty,omitempty" bson:"image,omitempty" binding:"omitempty,min=1,max=1000"` + Image *string `json:"image,omitempty" bson:"image,omitempty" binding:"omitempty,min=1,max=1000"` HealthCheckPath *string `json:"healthCheckPath,omitempty" bson:"healthCheckPath,omitempty" binding:"omitempty,min=0,max=1000,health_check_path"` // CustomDomain is the domain that the deployment will be available on. // The max length is set to 243 to allow for a subdomain when confirming the domain. diff --git a/pkg/auth/gin_keycloak.go b/pkg/auth/gin_keycloak.go index 7a89d0a1..3f769f48 100644 --- a/pkg/auth/gin_keycloak.go +++ b/pkg/auth/gin_keycloak.go @@ -7,9 +7,7 @@ import ( "encoding/base64" "encoding/json" "errors" - "github.com/kthcloud/go-deploy/models/mode" - "github.com/kthcloud/go-deploy/pkg/config" - "io/ioutil" + "io" "math/big" "net/http" "net/url" @@ -17,6 +15,9 @@ import ( "strings" "time" + "github.com/kthcloud/go-deploy/models/mode" + "github.com/kthcloud/go-deploy/pkg/config" + "github.com/gin-gonic/gin" "github.com/golang/glog" "github.com/patrickmn/go-cache" @@ -133,7 +134,7 @@ func getPublicKeyFromCacheOrBackend(keyId string, config KeycloakConfig) (KeyEnt return KeyEntry{}, err } defer resp.Body.Close() - body, _ := ioutil.ReadAll(resp.Body) + body, _ := io.ReadAll(resp.Body) var certs Certs err = json.Unmarshal(body, &certs) @@ -262,7 +263,6 @@ func authChain(kcConfig KeycloakConfig, accessCheckFunctions ...AccessCheckFunct } _ = ctx.AbortWithError(http.StatusForbidden, errors.New("access to the Resource is forbidden")) varianceControl <- false - return }() select { diff --git a/pkg/db/message_queue/client.go b/pkg/db/message_queue/client.go index 586b3ac6..76db7c36 100644 --- a/pkg/db/message_queue/client.go +++ b/pkg/db/message_queue/client.go @@ -4,14 +4,15 @@ import ( "context" "encoding/json" "fmt" + "github.com/kthcloud/go-deploy/pkg/db" "github.com/kthcloud/go-deploy/pkg/log" "github.com/redis/go-redis/v9" ) var ( - // QueueNotFoundErr is returned when a queue is not found. - QueueNotFoundErr = fmt.Errorf("queue not found") + // ErrQueueNotFound is returned when a queue is not found. + ErrQueueNotFound = fmt.Errorf("queue not found") ) // Client is used to manage key-value pairs in Redis. diff --git a/pkg/db/migrate/migrate.go b/pkg/db/migrate/migrate.go index e784982f..341fb872 100644 --- a/pkg/db/migrate/migrate.go +++ b/pkg/db/migrate/migrate.go @@ -1,3 +1,4 @@ +//lint:file-ignore // Ignore (SA1019) since we want to migrate deprecated. package migrator import ( diff --git a/pkg/db/resources/deployment_repo/db.go b/pkg/db/resources/deployment_repo/db.go index dd33866c..ae8b637d 100644 --- a/pkg/db/resources/deployment_repo/db.go +++ b/pkg/db/resources/deployment_repo/db.go @@ -20,7 +20,7 @@ import ( ) // Create creates a new deployment with the given params. -// It will return a NonUniqueFieldErr any unique index was violated. +// It will return a ErrNonUniqueField any unique index was violated. func (client *Client) Create(id, ownerID string, params *model.DeploymentCreateParams) (*model.Deployment, error) { appName := "main" @@ -82,7 +82,7 @@ func (client *Client) Create(id, ownerID string, params *model.DeploymentCreateP _, err := client.Collection.InsertOne(context.TODO(), deployment) if err != nil { if mongo.IsDuplicateKeyError(err) { - return nil, rErrors.NonUniqueFieldErr + return nil, rErrors.ErrNonUniqueField } return nil, fmt.Errorf("failed to create deployment. details: %w", err) @@ -92,7 +92,7 @@ func (client *Client) Create(id, ownerID string, params *model.DeploymentCreateP } // UpdateWithParams updates a deployment with the given update params. -// It will return a NonUniqueFieldErr any unique index was violated. +// It will return a ErrNonUniqueField any unique index was violated. func (client *Client) UpdateWithParams(id string, params *model.DeploymentUpdateParams) error { deployment, err := client.GetByID(id) if err != nil { @@ -150,7 +150,7 @@ func (client *Client) UpdateWithParams(id string, params *model.DeploymentUpdate ) if err != nil { if mongo.IsDuplicateKeyError(err) { - return rErrors.NonUniqueFieldErr + return rErrors.ErrNonUniqueField } return fmt.Errorf("failed to update deployment %s. details: %w", id, err) diff --git a/pkg/db/resources/errors/errors.go b/pkg/db/resources/errors/errors.go index 559aff36..e4e2222b 100644 --- a/pkg/db/resources/errors/errors.go +++ b/pkg/db/resources/errors/errors.go @@ -3,6 +3,6 @@ package errors import "fmt" var ( - // NonUniqueFieldErr is returned when a unique index in the database is violated. - NonUniqueFieldErr = fmt.Errorf("non unique field") + // ErrNonUniqueField is returned when a unique index in the database is violated. + ErrNonUniqueField = fmt.Errorf("non unique field") ) diff --git a/pkg/db/resources/event_repo/client.go b/pkg/db/resources/event_repo/client.go index 0cd9279e..58690ff1 100644 --- a/pkg/db/resources/event_repo/client.go +++ b/pkg/db/resources/event_repo/client.go @@ -35,8 +35,9 @@ func (client *Client) WithPagination(page, pageSize int) *Client { } // AddExtraFilter adds an extra custom filter to the client. -func (client *Client) AddExtraFilter(filter bson.D) *Client { - client.AddExtraFilter(filter) - +func (client *Client) AddExtraFilter(filters bson.D) *Client { + for _, filter := range filters { + client.ExtraFilter[filter.Key] = filter.Value + } return client } diff --git a/pkg/db/resources/gpu_group_repo/db.go b/pkg/db/resources/gpu_group_repo/db.go index 7178f211..6f789f31 100644 --- a/pkg/db/resources/gpu_group_repo/db.go +++ b/pkg/db/resources/gpu_group_repo/db.go @@ -28,7 +28,7 @@ func (client *Client) Create(name, displayName, zone, vendor, deviceID, vendorID err := client.CreateIfUnique(id, &group, bson.D{{Key: "id", Value: id}, {Key: "zone", Value: zone}}) if err != nil { if errors.Is(err, db.ErrUniqueConstraint) { - return GpuLeaseAlreadyExistsErr + return ErrGpuLeaseAlreadyExists } return err diff --git a/pkg/db/resources/gpu_group_repo/errors.go b/pkg/db/resources/gpu_group_repo/errors.go index c331d04a..dfb73415 100644 --- a/pkg/db/resources/gpu_group_repo/errors.go +++ b/pkg/db/resources/gpu_group_repo/errors.go @@ -3,6 +3,6 @@ package gpu_group_repo import "fmt" var ( - // GpuLeaseAlreadyExistsErr is returned when a GPU lease already exists for a user. - GpuLeaseAlreadyExistsErr = fmt.Errorf("gpu lease already exists") + // ErrGpuLeaseAlreadyExists is returned when a GPU lease already exists for a user. + ErrGpuLeaseAlreadyExists = fmt.Errorf("gpu lease already exists") ) diff --git a/pkg/db/resources/gpu_lease_repo/db.go b/pkg/db/resources/gpu_lease_repo/db.go index 9a1f9ba0..869bd438 100644 --- a/pkg/db/resources/gpu_lease_repo/db.go +++ b/pkg/db/resources/gpu_lease_repo/db.go @@ -27,7 +27,7 @@ func (client *Client) Create(id, userID, groupName string, leaseDuration float64 err := client.CreateIfUnique(id, &lease, bson.D{{Key: "userId", Value: userID}}) if err != nil { if errors.Is(err, db.ErrUniqueConstraint) { - return GpuLeaseAlreadyExistsErr + return ErrGpuLeaseAlreadyExists } return err @@ -45,7 +45,7 @@ func (client *Client) UpdateWithParams(id string, params *model.GpuLeaseUpdatePa err := client.SetWithBsonByID(id, update) if err != nil { if errors.Is(err, db.ErrUniqueConstraint) { - return VmAlreadyAttachedErr + return ErrVmAlreadyAttached } return err diff --git a/pkg/db/resources/gpu_lease_repo/errors.go b/pkg/db/resources/gpu_lease_repo/errors.go index b5ddad50..0d2dc78f 100644 --- a/pkg/db/resources/gpu_lease_repo/errors.go +++ b/pkg/db/resources/gpu_lease_repo/errors.go @@ -3,9 +3,9 @@ package gpu_lease_repo import "fmt" var ( - // GpuLeaseAlreadyExistsErr is returned when a GPU lease already exists for a user. - GpuLeaseAlreadyExistsErr = fmt.Errorf("gpu lease already exists") + // ErrGpuLeaseAlreadyExists is returned when a GPU lease already exists for a user. + ErrGpuLeaseAlreadyExists = fmt.Errorf("gpu lease already exists") - // VmAlreadyAttachedErr is returned when a VM is already attached to a GPU lease. - VmAlreadyAttachedErr = fmt.Errorf("vm already attached") + // ErrVmAlreadyAttached is returned when a VM is already attached to a GPU lease. + ErrVmAlreadyAttached = fmt.Errorf("vm already attached") ) diff --git a/pkg/db/resources/user_repo/db.go b/pkg/db/resources/user_repo/db.go index 3755a601..42f0462b 100644 --- a/pkg/db/resources/user_repo/db.go +++ b/pkg/db/resources/user_repo/db.go @@ -60,7 +60,7 @@ func (client *Client) Synchronize(id string, params *model.UserSynchronizeParams if err != nil { if errors.Is(err, db.ErrUniqueConstraint) { - return nil, rErrors.NonUniqueFieldErr + return nil, rErrors.ErrNonUniqueField } return nil, fmt.Errorf("failed to create user for %s. details: %w", id, err) diff --git a/pkg/db/resources/vm_repo/db.go b/pkg/db/resources/vm_repo/db.go index 462468d2..72881434 100644 --- a/pkg/db/resources/vm_repo/db.go +++ b/pkg/db/resources/vm_repo/db.go @@ -75,7 +75,7 @@ func (client *Client) Create(id, owner string, params *model.VmCreateParams) (*m _, err := client.Collection.InsertOne(context.TODO(), vm) if err != nil { if mongo.IsDuplicateKeyError(err) { - return nil, rErrors.NonUniqueFieldErr + return nil, rErrors.ErrNonUniqueField } return nil, fmt.Errorf("failed to create vm %s. details: %w", id, err) @@ -165,7 +165,7 @@ func (client *Client) UpdateWithParams(id string, params *model.VmUpdateParams) } if existAny { - return rErrors.NonUniqueFieldErr + return rErrors.ErrNonUniqueField } } } @@ -229,7 +229,7 @@ func (client *Client) UpdateWithParams(id string, params *model.VmUpdateParams) ) if err != nil { if mongo.IsDuplicateKeyError(err) { - return rErrors.NonUniqueFieldErr + return rErrors.ErrNonUniqueField } return fmt.Errorf("failed to update vm %s. details: %w", id, err) diff --git a/pkg/imp/harbor/harbor/client_test.go b/pkg/imp/harbor/harbor/client_test.go index 8fcaf92e..4f98a760 100644 --- a/pkg/imp/harbor/harbor/client_test.go +++ b/pkg/imp/harbor/harbor/client_test.go @@ -116,8 +116,8 @@ func TestClientSet(t *testing.T) { } var ( - result = "yes" - v = "1.2" + result = "yes" + // v = "1.2" username = "a" password = "b" ) diff --git a/pkg/intializer/system_services.go b/pkg/intializer/system_services.go index 5cc62f4e..5eccd838 100644 --- a/pkg/intializer/system_services.go +++ b/pkg/intializer/system_services.go @@ -2,6 +2,7 @@ package intializer import ( "errors" + "github.com/google/uuid" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/config" @@ -34,7 +35,7 @@ func EnsureSystemDeploymentsExists() error { Zone: strPtr(zone.Name), }) if err != nil { - if !errors.Is(err, sErrors.NonUniqueFieldErr) { + if !errors.Is(err, sErrors.ErrNonUniqueField) { return err } } diff --git a/pkg/intializer/test.go b/pkg/intializer/test.go index 41b75073..cc7c385c 100644 --- a/pkg/intializer/test.go +++ b/pkg/intializer/test.go @@ -3,6 +3,8 @@ package intializer import ( "errors" "fmt" + "time" + "github.com/google/uuid" "github.com/kthcloud/go-deploy/models/mode" "github.com/kthcloud/go-deploy/models/model" @@ -16,7 +18,6 @@ import ( "github.com/kthcloud/go-deploy/pkg/db/resources/vm_repo" "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/service" - "time" ) // CleanUpOldTests cleans up old E2E tests. @@ -84,7 +85,7 @@ func EnsureTestUsersExist() error { IsAdmin: user.IsAdmin, EffectiveRole: &user.EffectiveRole, }) - if err != nil && !errors.Is(err, rErrors.NonUniqueFieldErr) { + if err != nil && !errors.Is(err, rErrors.ErrNonUniqueField) { return fmt.Errorf("failed to synchronize user %s: %w", user.ID, err) } diff --git a/pkg/jobs/v2/deployment_jobs.go b/pkg/jobs/v2/deployment_jobs.go index 61be53a2..364e5435 100644 --- a/pkg/jobs/v2/deployment_jobs.go +++ b/pkg/jobs/v2/deployment_jobs.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" @@ -15,7 +17,6 @@ import ( "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/mitchellh/mapstructure" - "time" ) func CreateDeployment(job *model.Job) error { @@ -39,7 +40,7 @@ func CreateDeployment(job *model.Job) error { return jErrors.MakeTerminatedError(err) } - // If there was some error, we trigger a repair, since rerunning it would cause a NonUniqueFieldErr + // If there was some error, we trigger a repair, since rerunning it would cause a ErrNonUniqueField _ = service.V2(utils.GetAuthInfo(job)).Deployments().Repair(id) return jErrors.MakeTerminatedError(err) } @@ -100,7 +101,7 @@ func DeleteDeployment(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).Deployments().Delete(id) if err != nil { - if !errors.Is(err, sErrors.DeploymentNotFoundErr) { + if !errors.Is(err, sErrors.ErrDeploymentNotFound) { return jErrors.MakeFailedError(err) } } @@ -138,11 +139,11 @@ func UpdateDeployment(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).Deployments().Update(id, &update) if err != nil { switch { - case errors.Is(err, sErrors.DeploymentNotFoundErr): + case errors.Is(err, sErrors.ErrDeploymentNotFound): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.NonUniqueFieldErr): + case errors.Is(err, sErrors.ErrNonUniqueField): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.IngressHostInUseErr): + case errors.Is(err, sErrors.ErrIngressHostInUse): return jErrors.MakeTerminatedError(err) } @@ -172,7 +173,7 @@ func UpdateDeploymentOwner(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).Deployments().UpdateOwner(id, ¶ms) if err != nil { - if errors.Is(err, sErrors.DeploymentNotFoundErr) { + if errors.Is(err, sErrors.ErrDeploymentNotFound) { return jErrors.MakeTerminatedError(err) } diff --git a/pkg/jobs/v2/sm_jobs.go b/pkg/jobs/v2/sm_jobs.go index ca59dbd0..42447d2f 100644 --- a/pkg/jobs/v2/sm_jobs.go +++ b/pkg/jobs/v2/sm_jobs.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" @@ -13,7 +15,6 @@ import ( "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/mitchellh/mapstructure" - "time" ) func CreateSM(job *model.Job) error { @@ -33,7 +34,7 @@ func CreateSM(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).SMs().Create(id, userID, ¶ms) if err != nil { - // We always terminate these jobs, since rerunning it would cause a NonUniqueFieldErr + // We always terminate these jobs, since rerunning it would cause a ErrNonUniqueField return jErrors.MakeTerminatedError(err) } @@ -93,7 +94,7 @@ func DeleteSM(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).SMs().Delete(id) if err != nil { - if !errors.Is(err, sErrors.SmNotFoundErr) { + if !errors.Is(err, sErrors.ErrSmNotFound) { return jErrors.MakeFailedError(err) } } diff --git a/pkg/jobs/v2/vm_jobs.go b/pkg/jobs/v2/vm_jobs.go index 13332413..06fdbc6b 100644 --- a/pkg/jobs/v2/vm_jobs.go +++ b/pkg/jobs/v2/vm_jobs.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/job_repo" @@ -16,7 +18,6 @@ import ( sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/v2/vms/opts" "github.com/mitchellh/mapstructure" - "time" ) func CreateVM(job *model.Job) error { @@ -35,7 +36,7 @@ func CreateVM(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).VMs().Create(id, ownerID, ¶ms) if err != nil { - // If there was some error, we trigger a repair, since rerunning it would cause a NonUniqueFieldErr + // If there was some error, we trigger a repair, since rerunning it would cause a ErrNonUniqueField _ = service.V2(utils.GetAuthInfo(job)).VMs().Repair(id) return jErrors.MakeTerminatedError(err) } @@ -96,7 +97,7 @@ func DeleteVM(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).VMs().Delete(id) if err != nil { - if !errors.Is(err, sErrors.VmNotFoundErr) { + if !errors.Is(err, sErrors.ErrVmNotFound) { return jErrors.MakeFailedError(err) } } @@ -134,15 +135,15 @@ func UpdateVM(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).VMs().Update(id, &update) if err != nil { switch { - case errors.Is(err, sErrors.VmNotFoundErr): + case errors.Is(err, sErrors.ErrVmNotFound): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.NonUniqueFieldErr): + case errors.Is(err, sErrors.ErrNonUniqueField): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.IngressHostInUseErr): + case errors.Is(err, sErrors.ErrIngressHostInUse): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.NoPortsAvailableErr): + case errors.Is(err, sErrors.ErrNoPortsAvailable): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.SnapshotNotFoundErr): + case errors.Is(err, sErrors.ErrSnapshotNotFound): return jErrors.MakeTerminatedError(err) } @@ -174,11 +175,11 @@ func CreateGpuLease(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).VMs().GpuLeases().Create(id, userID, ¶ms) if err != nil { switch { - case errors.Is(err, sErrors.VmNotFoundErr): + case errors.Is(err, sErrors.ErrVmNotFound): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.GpuLeaseAlreadyExistsErr): + case errors.Is(err, sErrors.ErrGpuLeaseAlreadyExists): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.GpuNotFoundErr): + case errors.Is(err, sErrors.ErrGpuNotFound): return jErrors.MakeTerminatedError(err) } @@ -204,11 +205,11 @@ func UpdateGpuLease(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).VMs().GpuLeases().Update(id, ¶ms) if err != nil { switch { - case errors.Is(err, sErrors.GpuLeaseNotFoundErr): + case errors.Is(err, sErrors.ErrGpuLeaseNotFound): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.GpuLeaseNotAssignedErr): + case errors.Is(err, sErrors.ErrGpuLeaseNotAssigned): return jErrors.MakeTerminatedError(err) - case errors.Is(err, sErrors.VmAlreadyAttachedErr): + case errors.Is(err, sErrors.ErrVmAlreadyAttached): return jErrors.MakeTerminatedError(err) } @@ -229,7 +230,7 @@ func DeleteGpuLease(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).VMs().GpuLeases().Delete(id) if err != nil { switch { - case errors.Is(err, sErrors.GpuNotFoundErr): + case errors.Is(err, sErrors.ErrGpuNotFound): return jErrors.MakeTerminatedError(err) } @@ -338,7 +339,7 @@ func UpdateVmOwner(job *model.Job) error { err = service.V2(utils.GetAuthInfo(job)).VMs().UpdateOwner(id, ¶ms) if err != nil { - if errors.Is(err, sErrors.VmNotFoundErr) { + if errors.Is(err, sErrors.ErrVmNotFound) { return jErrors.MakeTerminatedError(err) } diff --git a/pkg/services/errors/errors.go b/pkg/services/errors/errors.go index 3f9d93e3..9dae35d2 100644 --- a/pkg/services/errors/errors.go +++ b/pkg/services/errors/errors.go @@ -18,9 +18,9 @@ func NewHostsFailedErr(hosts []string) error { } var ( - // NoHostsErr is returned when no hosts are found - NoHostsErr = fmt.Errorf("no hosts found") + // ErrNoHosts is returned when no hosts are found + ErrNoHosts = fmt.Errorf("no hosts found") - // NoClustersErr is returned when no clusters are found - NoClustersErr = fmt.Errorf("no clusters found") + // ErrNoClusters is returned when no clusters are found + ErrNoClusters = fmt.Errorf("no clusters found") ) diff --git a/pkg/services/logger/pod_logger.go b/pkg/services/logger/pod_logger.go index 9195e945..1e0c8fbf 100644 --- a/pkg/services/logger/pod_logger.go +++ b/pkg/services/logger/pod_logger.go @@ -5,6 +5,9 @@ import ( "encoding/json" "errors" "fmt" + "os" + "time" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -16,8 +19,6 @@ import ( "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/utils" - "os" - "time" ) // PodLogger is a worker that logs deployments. @@ -84,7 +85,7 @@ func OnPodEvent(ctx context.Context, zone *configModels.Zone, cancelFuncs map[st err = service.V2().Deployments().K8s().SetupPodLogStream(loggerCtx, zone, logEvent.PodName, lastLogged, onLog) if err != nil { cancelFunc() - if errors.Is(err, sErrors.DeploymentNotFoundErr) { + if errors.Is(err, sErrors.ErrDeploymentNotFound) { return nil } @@ -95,14 +96,14 @@ func OnPodEvent(ctx context.Context, zone *configModels.Zone, cancelFuncs map[st // Set up a loop to update ownership of pod name go func(ctx, loggerCtx context.Context) { - tick := time.Tick(LoggerUpdate) + tick := time.NewTicker(LoggerUpdate) for { select { case <-ctx.Done(): return case <-loggerCtx.Done(): return - case <-tick: + case <-tick.C: didSet, err := kvc.SetXX(OwnerLogKey(logEvent.PodName, zone.Name), name, LoggerLifetime) if err != nil { utils.PrettyPrintError(fmt.Errorf("failed to update ownership of pod %s. details: %w", logEvent.PodName, err)) diff --git a/pkg/services/logger/pod_logger_control.go b/pkg/services/logger/pod_logger_control.go index 486fb307..03d33a8d 100644 --- a/pkg/services/logger/pod_logger_control.go +++ b/pkg/services/logger/pod_logger_control.go @@ -3,6 +3,8 @@ package logger import ( "context" "fmt" + "time" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/db/key_value" @@ -11,7 +13,6 @@ import ( "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" "github.com/kthcloud/go-deploy/service" "github.com/kthcloud/go-deploy/utils" - "time" ) type LogEvent struct { @@ -124,7 +125,6 @@ func PodLoggerControl(ctx context.Context) error { return } - return }) if err != nil { return fmt.Errorf("failed to set up deployment status watcher for zone %s. details: %w", zone.Name, err) @@ -132,12 +132,12 @@ func PodLoggerControl(ctx context.Context) error { // Synchronize the existing pods with the loggers at an interval go func(ctx context.Context) { - ticker := time.Tick(LoggerSynchronize) + ticker := time.NewTicker(LoggerSynchronize) for { select { case <-ctx.Done(): return - case <-ticker: + case <-ticker.C: pods, err := service.V2().Deployments().K8s().Pods(&z) if err != nil { utils.PrettyPrintError(fmt.Errorf("failed to get pods for zone %s. details: %w", z.Name, err)) diff --git a/pkg/services/system_state_poll/gpu_info_worker.go b/pkg/services/system_state_poll/gpu_info_worker.go index 7d4d026d..99cdb109 100644 --- a/pkg/services/system_state_poll/gpu_info_worker.go +++ b/pkg/services/system_state_poll/gpu_info_worker.go @@ -2,6 +2,9 @@ package system_state_poll import ( "fmt" + "sync" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" @@ -9,8 +12,6 @@ import ( wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" "github.com/kthcloud/go-deploy/pkg/subsystems/host_api" "github.com/kthcloud/go-deploy/utils" - "sync" - "time" ) func GetHostGpuInfo() ([]body.HostGpuInfo, error) { @@ -81,7 +82,7 @@ func GpuInfoWorker() error { } if len(hostGpuInfo) == 0 { - return wErrors.NoHostsErr + return wErrors.ErrNoHosts } return system_gpu_info_repo.New(500).Save(&body.TimestampedSystemGpuInfo{ diff --git a/pkg/services/system_state_poll/stats_worker.go b/pkg/services/system_state_poll/stats_worker.go index 7ec36604..a8680242 100644 --- a/pkg/services/system_state_poll/stats_worker.go +++ b/pkg/services/system_state_poll/stats_worker.go @@ -2,6 +2,10 @@ package system_state_poll import ( "fmt" + "log" + "sync" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/db/resources/system_stats_repo" @@ -9,9 +13,6 @@ import ( "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" "github.com/kthcloud/go-deploy/utils" "k8s.io/client-go/kubernetes" - "log" - "sync" - "time" ) func GetClusterStats() ([]body.ClusterStats, error) { @@ -61,7 +62,7 @@ func StatsWorker() error { } if clusterStats == nil { - return wErrors.NoClustersErr + return wErrors.ErrNoClusters } collected := body.SystemStats{K8sStats: body.K8sStats{PodCount: 0, Clusters: clusterStats}} diff --git a/pkg/services/system_state_poll/status_worker.go b/pkg/services/system_state_poll/status_worker.go index 0016950e..e62b7ba0 100644 --- a/pkg/services/system_state_poll/status_worker.go +++ b/pkg/services/system_state_poll/status_worker.go @@ -2,6 +2,9 @@ package system_state_poll import ( "fmt" + "sync" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" @@ -9,8 +12,6 @@ import ( wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" "github.com/kthcloud/go-deploy/pkg/subsystems/host_api" "github.com/kthcloud/go-deploy/utils" - "sync" - "time" ) func GetHostStatuses() ([]body.HostStatus, error) { @@ -81,7 +82,7 @@ func StatusWorker() error { } if len(hostStatuses) == 0 { - return wErrors.NoHostsErr + return wErrors.ErrNoHosts } status := body.SystemStatus{ diff --git a/pkg/services/workers.go b/pkg/services/workers.go index 5f05f9e8..37a46257 100644 --- a/pkg/services/workers.go +++ b/pkg/services/workers.go @@ -4,12 +4,13 @@ import ( "context" "errors" "fmt" + "strings" + "time" + "github.com/kthcloud/go-deploy/pkg/db/resources/host_repo" "github.com/kthcloud/go-deploy/pkg/log" wErrors "github.com/kthcloud/go-deploy/pkg/services/errors" "github.com/kthcloud/go-deploy/utils" - "strings" - "time" ) // Worker is a wrapper for a worker main function and reports the workers status every second. @@ -28,14 +29,14 @@ func Worker(ctx context.Context, name string, work func(context.Context) error) } }() - reportTick := time.Tick(1 * time.Second) - cleanUpTick := time.Tick(300 * time.Second) + reportTick := time.NewTicker(1 * time.Second) + cleanUpTick := time.NewTicker(300 * time.Second) for { select { - case <-reportTick: + case <-reportTick.C: ReportUp(name) - case <-cleanUpTick: + case <-cleanUpTick.C: CleanUp() case <-internalCtx.Done(): return @@ -52,16 +53,16 @@ func Worker(ctx context.Context, name string, work func(context.Context) error) func PeriodicWorker(ctx context.Context, name string, work func() error, interval time.Duration) { defer OnStop(name) - reportTick := time.Tick(1 * time.Second) - tick := time.Tick(interval) + reportTick := time.NewTicker(1 * time.Second) + tick := time.NewTicker(interval) errorSleep := interval for { select { - case <-reportTick: + case <-reportTick.C: ReportUp(name) - case <-tick: + case <-tick.C: if err := work(); err != nil { // If errors is HostsFailedErr, disable the hosts var hostsFailedErr *wErrors.HostsFailedErr @@ -75,7 +76,7 @@ func PeriodicWorker(ctx context.Context, name string, work func() error, interva } // It's too verbose to print when no hosts or clusters are available, so we skip that - if !errors.Is(err, wErrors.NoClustersErr) && !errors.Is(err, wErrors.NoHostsErr) { + if !errors.Is(err, wErrors.ErrNoClusters) && !errors.Is(err, wErrors.ErrNoHosts) { utils.PrettyPrintError(fmt.Errorf("%s failed (sleeping for extra %s): %w", name, errorSleep.String(), err)) } time.Sleep(errorSleep) diff --git a/pkg/subsystems/harbor/common.go b/pkg/subsystems/harbor/common.go index 5e33098f..c23475dd 100644 --- a/pkg/subsystems/harbor/common.go +++ b/pkg/subsystems/harbor/common.go @@ -1,18 +1,16 @@ package harbor import ( - "encoding/json" "errors" - "fmt" + "net/http" + "strings" + "github.com/go-openapi/runtime" "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/project" "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/repository" "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robot" "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/robotv1" "github.com/kthcloud/go-deploy/pkg/imp/harbor/sdk/v2.0/client/webhook" - "github.com/kthcloud/go-deploy/utils/requestutils" - "net/http" - "strings" ) // IsNotFoundErr checks if the error is a not found error. @@ -131,15 +129,15 @@ func IsNotFoundErr(err error) bool { } // doJSONRequest is a helper function to do a JSON request to the Harbor API. -func (client *Client) doJSONRequest(method string, relativePath string, requestBody interface{}) (*http.Response, error) { - jsonBody, err := json.Marshal(requestBody) - if err != nil { - return nil, err - } - - fullURL := fmt.Sprintf("%s%s", client.url, relativePath) - return requestutils.DoRequestBasicAuth(method, fullURL, jsonBody, nil, client.username, client.password) -} +// func (client *Client) doJSONRequest(method string, relativePath string, requestBody interface{}) (*http.Response, error) { +// jsonBody, err := json.Marshal(requestBody) +// if err != nil { +// return nil, err +// } + +// fullURL := fmt.Sprintf("%s%s", client.url, relativePath) +// return requestutils.DoRequestBasicAuth(method, fullURL, jsonBody, nil, client.username, client.password) +// } // createProject creates a project in Harbor. // Needed since the installed Harbor client does not return credentials. diff --git a/pkg/subsystems/k8s/errors/errors.go b/pkg/subsystems/k8s/errors/errors.go index 33a648e7..b2d2bd06 100644 --- a/pkg/subsystems/k8s/errors/errors.go +++ b/pkg/subsystems/k8s/errors/errors.go @@ -3,9 +3,9 @@ package errors import "fmt" var ( - // IngressHostInUseErr is returned when the ingress host is already in use. - IngressHostInUseErr = fmt.Errorf("ingress host is already in use") + // ErrIngressHostInUse is returned when the ingress host is already in use. + ErrIngressHostInUse = fmt.Errorf("ingress host is already in use") - // NotFoundErr is returned when a resource is not found. - NotFoundErr = fmt.Errorf("resource not found") + // ErrNotFound is returned when a resource is not found. + ErrNotFound = fmt.Errorf("resource not found") ) diff --git a/pkg/subsystems/k8s/ingress.go b/pkg/subsystems/k8s/ingress.go index 432a0452..a1adf61f 100644 --- a/pkg/subsystems/k8s/ingress.go +++ b/pkg/subsystems/k8s/ingress.go @@ -3,12 +3,13 @@ package k8s import ( "context" "fmt" + "strings" + "time" + "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/errors" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "strings" - "time" ) // ReadIngress reads a Ingress from Kubernetes. @@ -55,7 +56,7 @@ func (client *Client) CreateIngress(public *models.IngressPublic) (*models.Ingre res, err := client.K8sClient.NetworkingV1().Ingresses(public.Namespace).Create(context.TODO(), manifest, metav1.CreateOptions{}) if err != nil { if strings.Contains(err.Error(), "is already defined in ingress") { - return nil, makeError(errors.IngressHostInUseErr) + return nil, makeError(errors.ErrIngressHostInUse) } return nil, makeError(err) @@ -78,7 +79,7 @@ func (client *Client) UpdateIngress(public *models.IngressPublic) (*models.Ingre ingress, err := client.K8sClient.NetworkingV1().Ingresses(public.Namespace).Update(context.TODO(), CreateIngressManifest(public), metav1.UpdateOptions{}) if err != nil && !IsNotFoundErr(err) { if strings.Contains(err.Error(), "is already defined in ingress") { - return nil, makeError(errors.IngressHostInUseErr) + return nil, makeError(errors.ErrIngressHostInUse) } return nil, makeError(err) diff --git a/pkg/subsystems/k8s/logs.go b/pkg/subsystems/k8s/logs.go index 937d6f00..f81fef9f 100644 --- a/pkg/subsystems/k8s/logs.go +++ b/pkg/subsystems/k8s/logs.go @@ -4,39 +4,38 @@ import ( "bufio" "context" "fmt" + "io" + "strings" + "time" + "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" "github.com/kthcloud/go-deploy/service/errors" - "golang.org/x/exp/maps" - "io" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sort" - "strings" - "time" ) // getPodNames gets the names of all pods for a deployment // This is used when setting up a log stream for a deployment -func (client *Client) getPodNames(namespace, deploymentName string) ([]string, error) { - pods, err := client.K8sClient.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", keys.LabelDeployName, deploymentName), - }) - if err != nil { - return nil, err - } - - podNames := make([]string, 0) - for _, pod := range pods.Items { - if pod.Status.Phase != v1.PodRunning { - continue - } - podNames = append(podNames, pod.Name) - } - - return podNames, nil -} +// func (client *Client) getPodNames(namespace, deploymentName string) ([]string, error) { +// pods, err := client.K8sClient.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ +// LabelSelector: fmt.Sprintf("%s=%s", keys.LabelDeployName, deploymentName), +// }) +// if err != nil { +// return nil, err +// } + +// podNames := make([]string, 0) +// for _, pod := range pods.Items { +// if pod.Status.Phase != v1.PodRunning { +// continue +// } +// podNames = append(podNames, pod.Name) +// } + +// return podNames, nil +// } // SetupPodLogStream reads logs from a pod and sends them to the callback function func (client *Client) SetupPodLogStream(ctx context.Context, podName string, from time.Time, onLog func(deploymentName string, lines []models.LogLine)) error { @@ -46,13 +45,13 @@ func (client *Client) SetupPodLogStream(ctx context.Context, podName string, fro deploymentName := client.getDeploymentName(podName) if deploymentName == "" { - return makeError(errors.ResourceNotFoundErr) + return makeError(errors.ErrResourceNotFound) } logStream, err := client.getPodLogStream(ctx, client.Namespace, podName, from) if err != nil { if IsNotFoundErr(err) { - return makeError(errors.ResourceNotFoundErr) + return makeError(errors.ErrResourceNotFound) } return makeError(err) @@ -172,18 +171,18 @@ func isExitLine(line string) bool { // getFreePodNumber is a helper function that gets the next free pod number for a deployment // The number is used as a unique nice-to-read identifier for a pod. -func getFreePodNumber(activeStreams map[string]int) int { - values := maps.Values(activeStreams) +// func getFreePodNumber(activeStreams map[string]int) int { +// values := maps.Values(activeStreams) - sort.Slice(values, func(i, j int) bool { - return values[i] < values[j] - }) +// sort.Slice(values, func(i, j int) bool { +// return values[i] < values[j] +// }) - for i := 0; i < len(values); i++ { - if i != values[i] { - return i - } - } +// for i := 0; i < len(values); i++ { +// if i != values[i] { +// return i +// } +// } - return len(values) -} +// return len(values) +// } diff --git a/pkg/subsystems/k8s/manifests.go b/pkg/subsystems/k8s/manifests.go index 8a8461fa..d745bd37 100644 --- a/pkg/subsystems/k8s/manifests.go +++ b/pkg/subsystems/k8s/manifests.go @@ -2,6 +2,9 @@ package k8s import ( "fmt" + "strings" + "time" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" "github.com/kthcloud/go-deploy/utils" @@ -16,8 +19,6 @@ import ( kubevirtv1 "kubevirt.io/api/core/v1" snapshotalpha1 "kubevirt.io/api/snapshot/v1alpha1" cdibetav1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1" - "strings" - "time" ) const ( @@ -611,7 +612,7 @@ func CreateVmManifest(public *models.VmPublic, resourceVersion ...string) *kubev Resources: kubevirtv1.ResourceRequirements{ Requests: apiv1.ResourceList{ apiv1.ResourceMemory: resource.MustParse(fmt.Sprintf("%dGi", public.RAM)), - apiv1.ResourceCPU: resource.MustParse(fmt.Sprintf("250m")), + apiv1.ResourceCPU: resource.MustParse("250m"), }, Limits: apiv1.ResourceList{ apiv1.ResourceMemory: resource.MustParse(fmt.Sprintf("%dGi", public.RAM)), diff --git a/pkg/subsystems/k8s/pod.go b/pkg/subsystems/k8s/pod.go index 81ea91e9..20214dd9 100644 --- a/pkg/subsystems/k8s/pod.go +++ b/pkg/subsystems/k8s/pod.go @@ -2,6 +2,7 @@ package k8s import ( "context" + "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" v1 "k8s.io/api/core/v1" @@ -83,11 +84,7 @@ func (client *Client) SetupPodWatcher(ctx context.Context, callback func(podName } } - if !allowed { - return false - } - - return true + return allowed } _, err := podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ diff --git a/pkg/subsystems/k8s/status.go b/pkg/subsystems/k8s/status.go index df1c4791..ae49c0c4 100644 --- a/pkg/subsystems/k8s/status.go +++ b/pkg/subsystems/k8s/status.go @@ -3,6 +3,10 @@ package k8s import ( "context" "fmt" + "regexp" + "strings" + "time" + "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/keys" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" @@ -12,9 +16,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/watch" kubevirtv1 "kubevirt.io/api/core/v1" - "regexp" - "strings" - "time" ) // SetupStatusWatcher sets up a status watcher for a given resource type in a namespace @@ -35,8 +36,8 @@ func (client *Client) SetupStatusWatcher(ctx context.Context, resourceType strin return nil } -func (client *Client) deploymentStatusWatcher(ctx context.Context, handler func(string, interface{}), opts ...opts.WatcherOpts) error { - setupDeploymentWatcher := func(namespace string) (watch.Interface, error) { +func (client *Client) deploymentStatusWatcher(ctx context.Context, handler func(string, interface{}), _ ...opts.WatcherOpts) error { + setupDeploymentWatcher := func(_ string) (watch.Interface, error) { statusChan, err := client.K8sClient.AppsV1().Deployments(client.Namespace).Watch(ctx, metav1.ListOptions{Watch: true}) if err != nil { return nil, err @@ -49,10 +50,6 @@ func (client *Client) deploymentStatusWatcher(ctx context.Context, handler func( return statusChan, nil } - hello := "hello" - - strings.HasSuffix(hello, "o") - watcher, err := setupDeploymentWatcher(client.Namespace) if err != nil { return err @@ -62,7 +59,7 @@ func (client *Client) deploymentStatusWatcher(ctx context.Context, handler func( go func() { // For now, the watch stops working sometimes, so we need to restart it every 10 seconds // This is a temporary fix until we find the root cause - recreateInterval := time.Tick(20 * time.Second) + recreateInterval := time.NewTicker(20 * time.Second) for { select { @@ -89,7 +86,7 @@ func (client *Client) deploymentStatusWatcher(ctx context.Context, handler func( }) } } - case <-recreateInterval: + case <-recreateInterval.C: if watcher != nil { watcher.Stop() } @@ -109,8 +106,8 @@ func (client *Client) deploymentStatusWatcher(ctx context.Context, handler func( return nil } -func (client *Client) vmStatusWatcher(ctx context.Context, handler func(string, interface{}), opts ...opts.WatcherOpts) error { - setupVmWatcher := func(namespace string) (watch.Interface, error) { +func (client *Client) vmStatusWatcher(ctx context.Context, handler func(string, interface{}), _ ...opts.WatcherOpts) error { + setupVmWatcher := func(_ string) (watch.Interface, error) { statusChan, err := client.KubeVirtK8sClient.KubevirtV1().VirtualMachines(client.Namespace).Watch(ctx, metav1.ListOptions{Watch: true}) if err != nil { return nil, err @@ -132,7 +129,7 @@ func (client *Client) vmStatusWatcher(ctx context.Context, handler func(string, go func() { // For now, the watch stops working sometimes, so we need to restart it every 10 seconds // This is a temporary fix until we find the root cause - recreateInterval := time.Tick(20 * time.Second) + recreateInterval := time.NewTicker(20 * time.Second) for { select { @@ -142,7 +139,7 @@ func (client *Client) vmStatusWatcher(ctx context.Context, handler func(string, vmStatus := models.CreateVmStatusFromRead(vm) handler(vmStatus.Name, vmStatus) } - case <-recreateInterval: + case <-recreateInterval.C: if watcher != nil { watcher.Stop() } @@ -162,8 +159,8 @@ func (client *Client) vmStatusWatcher(ctx context.Context, handler func(string, return nil } -func (client *Client) vmiStatusWatcher(ctx context.Context, handler func(string, interface{}), opts ...opts.WatcherOpts) error { - setupVmWatcher := func(namespace string) (watch.Interface, error) { +func (client *Client) vmiStatusWatcher(ctx context.Context, handler func(string, interface{}), _ ...opts.WatcherOpts) error { + setupVmWatcher := func(_ string) (watch.Interface, error) { statusChan, err := client.KubeVirtK8sClient.KubevirtV1().VirtualMachineInstances(client.Namespace).Watch(ctx, metav1.ListOptions{Watch: true}) if err != nil { return nil, err @@ -185,7 +182,7 @@ func (client *Client) vmiStatusWatcher(ctx context.Context, handler func(string, go func() { // For now, the watch stops working sometimes, so we need to restart it every 10 seconds // This is a temporary fix until we find the root cause - recreateInterval := time.Tick(20 * time.Second) + recreateInterval := time.NewTicker(20 * time.Second) for { select { @@ -195,7 +192,7 @@ func (client *Client) vmiStatusWatcher(ctx context.Context, handler func(string, vmiStatus := models.CreateVmiStatusFromRead(vmi) handler(vmiStatus.Name, vmiStatus) } - case <-recreateInterval: + case <-recreateInterval.C: if watcher != nil { watcher.Stop() } @@ -215,8 +212,8 @@ func (client *Client) vmiStatusWatcher(ctx context.Context, handler func(string, return nil } -func (client *Client) eventWatcher(ctx context.Context, handler func(string, interface{}), opts ...opts.WatcherOpts) error { - setupEventWatcher := func(namespace string) (watch.Interface, error) { +func (client *Client) eventWatcher(ctx context.Context, handler func(string, interface{}), _ ...opts.WatcherOpts) error { + setupEventWatcher := func(_ string) (watch.Interface, error) { statusChan, err := client.K8sClient.CoreV1().Events(client.Namespace).Watch(ctx, metav1.ListOptions{ // Fields involvesObject.kind=Pod and type=Warning and reason=FailedMount or BackOff or Failed FieldSelector: "involvedObject.kind=Pod,type=Warning", @@ -241,7 +238,7 @@ func (client *Client) eventWatcher(ctx context.Context, handler func(string, int resultsChan := watcher.ResultChan() go func() { // For now, the watch stops working sometimes, so we need to restart it every 300 seconds - recreateInterval := time.Tick(300 * time.Second) + recreateInterval := time.NewTicker(300 * time.Second) for { select { @@ -345,7 +342,7 @@ func (client *Client) eventWatcher(ctx context.Context, handler func(string, int }) }(e) } - case <-recreateInterval: + case <-recreateInterval.C: if watcher != nil { watcher.Stop() } diff --git a/routers/api/v2/api_key.go b/routers/api/v2/api_key.go index 8ca25d0c..511f7add 100644 --- a/routers/api/v2/api_key.go +++ b/routers/api/v2/api_key.go @@ -42,7 +42,7 @@ func CreateApiKey(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -55,12 +55,12 @@ func CreateApiKey(c *gin.Context) { apiKey, err := deployV2.Users().ApiKeys().Create(requestURI.UserID, &requestBody) if err != nil { switch { - case errors.Is(err, sErrors.UserNotFoundErr): + case errors.Is(err, sErrors.ErrUserNotFound): context.NotFound("User not found") - case errors.Is(err, sErrors.ApiKeyNameTakenErr): + case errors.Is(err, sErrors.ErrApiKeyNameTaken): context.UserError("API key name already taken") default: - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) } return } diff --git a/routers/api/v2/deployment.go b/routers/api/v2/deployment.go index 78f6b427..46756dee 100644 --- a/routers/api/v2/deployment.go +++ b/routers/api/v2/deployment.go @@ -51,7 +51,7 @@ func GetDeployment(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -65,7 +65,7 @@ func GetDeployment(c *gin.Context) { } if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -105,7 +105,7 @@ func ListDeployments(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -124,7 +124,7 @@ func ListDeployments(c *gin.Context) { Shared: true, }) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -166,13 +166,13 @@ func CreateDeployment(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } effectiveRole := auth.GetEffectiveRole() if effectiveRole == nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -180,7 +180,7 @@ func CreateDeployment(c *gin.Context) { doesNotAlreadyExists, err := deployV2.Deployments().NameAvailable(requestBody.Name) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -220,7 +220,7 @@ func CreateDeployment(c *gin.Context) { return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -234,7 +234,7 @@ func CreateDeployment(c *gin.Context) { }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -270,7 +270,7 @@ func DeleteDeployment(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -278,7 +278,7 @@ func DeleteDeployment(c *gin.Context) { currentDeployment, err := deployV2.Deployments().Get(requestURI.DeploymentID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -300,12 +300,12 @@ func DeleteDeployment(c *gin.Context) { return } - if errors.Is(err, sErrors.DeploymentNotFoundErr) { + if errors.Is(err, sErrors.ErrDeploymentNotFound) { context.NotFound("Deployment not found") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -316,7 +316,7 @@ func DeleteDeployment(c *gin.Context) { "authInfo": auth, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -357,7 +357,7 @@ func UpdateDeployment(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -365,7 +365,7 @@ func UpdateDeployment(c *gin.Context) { deployment, err := deployV2.Deployments().Get(requestURI.DeploymentID, opts.GetOpts{Shared: true}) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } if deployment == nil { @@ -376,7 +376,7 @@ func UpdateDeployment(c *gin.Context) { if requestBody.Name != nil { available, err := deployV2.Deployments().NameAvailable(*requestBody.Name) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -394,7 +394,7 @@ func UpdateDeployment(c *gin.Context) { return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -412,7 +412,7 @@ func UpdateDeployment(c *gin.Context) { }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/deployment_ci_config.go b/routers/api/v2/deployment_ci_config.go index 73079fe7..def4416f 100644 --- a/routers/api/v2/deployment_ci_config.go +++ b/routers/api/v2/deployment_ci_config.go @@ -34,23 +34,23 @@ func GetCiConfig(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } config, err := service.V2(auth).Deployments().GetCiConfig(requestURI.DeploymentID) if err != nil { - if errors.Is(err, dErrors.DeploymentNotFoundErr) { + if errors.Is(err, dErrors.ErrDeploymentNotFound) { context.NotFound("Deployment not found") return } - if errors.Is(err, dErrors.DeploymentHasNotCiConfigErr) { + if errors.Is(err, dErrors.ErrDeploymentHasNoCiConfig) { context.UserError("Deployment has not CI config (not a custom deployment)") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/deployment_command.go b/routers/api/v2/deployment_command.go index 402e4d0d..29d2b911 100644 --- a/routers/api/v2/deployment_command.go +++ b/routers/api/v2/deployment_command.go @@ -42,7 +42,7 @@ func DoDeploymentCommand(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -50,7 +50,7 @@ func DoDeploymentCommand(c *gin.Context) { deployment, err := deployV2.Deployments().Get(requestURI.DeploymentID, opts.GetOpts{Shared: true}) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/deployment_hook.go b/routers/api/v2/deployment_hook.go index 724775c7..d73bcb7b 100644 --- a/routers/api/v2/deployment_hook.go +++ b/routers/api/v2/deployment_hook.go @@ -4,6 +4,9 @@ import ( "encoding/base64" "errors" "fmt" + "strings" + "time" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" @@ -11,8 +14,6 @@ import ( "github.com/kthcloud/go-deploy/service" sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/v2/deployments/opts" - "strings" - "time" ) // HandleHarborHook @@ -35,7 +36,7 @@ func HandleHarborHook(c *gin.Context) { token, err := getHarborTokenFromAuthHeader(context) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -60,7 +61,7 @@ func HandleHarborHook(c *gin.Context) { deployment, err := deployV2.Deployments().Get("", opts.GetOpts{HarborWebhook: &webhook}) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -88,12 +89,12 @@ func HandleHarborHook(c *gin.Context) { return } - if errors.Is(err, sErrors.DeploymentNotFoundErr) { + if errors.Is(err, sErrors.ErrDeploymentNotFound) { context.NotFound("Deployment not found") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } } diff --git a/routers/api/v2/deployment_logs.go b/routers/api/v2/deployment_logs.go index f6e800b2..601b8163 100644 --- a/routers/api/v2/deployment_logs.go +++ b/routers/api/v2/deployment_logs.go @@ -39,7 +39,7 @@ func GetLogs(c *gin.Context) { auth, err := WithAuth(&sysContext) if err != nil { - sysContext.ServerError(err, AuthInfoNotAvailableErr) + sysContext.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -63,12 +63,12 @@ func GetLogs(c *gin.Context) { err = deployV2.Deployments().SetupLogStream(requestURI.DeploymentID, ctx, handler, 25) if err != nil { - if errors.Is(err, errors2.DeploymentNotFoundErr) { + if errors.Is(err, errors2.ErrDeploymentNotFound) { sysContext.NotFound("Deployment not found") return } - sysContext.ServerError(err, InternalError) + sysContext.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/discover.go b/routers/api/v2/discover.go index e20b2720..cf000b72 100644 --- a/routers/api/v2/discover.go +++ b/routers/api/v2/discover.go @@ -19,7 +19,7 @@ func Discover(c *gin.Context) { discover, err := service.V2().Discovery().Discover() if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/errors.go b/routers/api/v2/errors.go index efc9b1fd..584b8e51 100644 --- a/routers/api/v2/errors.go +++ b/routers/api/v2/errors.go @@ -3,31 +3,31 @@ package v2 import "fmt" var ( - // AuthInfoNotAvailableErr is returned when the auth info is not available - AuthInfoNotAvailableErr = fmt.Errorf("auth info not available") - // AuthInfoSetupFailedErr is returned when the auth info setup failed - AuthInfoSetupFailedErr = fmt.Errorf("auth info setup failed") - // InternalError is returned when an internal error occurs. + // ErrAuthInfoNotAvailable is returned when the auth info is not available + ErrAuthInfoNotAvailable = fmt.Errorf("auth info not available") + // ErrAuthInfoSetupFailed is returned when the auth info setup failed + ErrAuthInfoSetupFailed = fmt.Errorf("auth info setup failed") + // ErrInternal is returned when an internal error occurs. // This is a generic error that should not be returned in the API, but rather logged - InternalError = fmt.Errorf("internal error") - // NoAvailableGpuErr is returned when there are no available GPUs. + ErrInternal = fmt.Errorf("internal error") + // ErrNoAvailableGpu is returned when there are no available GPUs. // This is normally caused by all GPUs being leased - NoAvailableGpuErr = fmt.Errorf("no available GPUs") - // GpuNotAvailableErr is returned when the GPU is not available. + ErrNoAvailableGpu = fmt.Errorf("no available GPUs") + // ErrGpuNotAvailable is returned when the GPU is not available. // This is normally caused by the host being down - GpuNotAvailableErr = fmt.Errorf("GPU not available") - // HostNotAvailableErr is returned when the host is not available. + ErrGpuNotAvailable = fmt.Errorf("GPU not available") + // ErrHostNotAvailable is returned when the host is not available. // This is normally caused by the host being down or disabled/in maintenance - HostNotAvailableErr = fmt.Errorf("host not available") - // VmTooLargeForHostErr is returned when the VM is too large for the host. + ErrHostNotAvailable = fmt.Errorf("host not available") + // ErrVmToLargeForHost is returned when the VM is too large for the host. // This is normally caused by the VM requesting more resources than the host has available - VmTooLargeForHostErr = fmt.Errorf("VM too large for host") - // VmNotReadyErr is returned when the VM is not ready. + ErrVmToLargeForHost = fmt.Errorf("VM too large for host") + // ErrVmNotReady is returned when the VM is not ready. // This is normally caused by the internal CloudStack VM not being created yet - VmNotReadyErr = fmt.Errorf("VM not ready") + ErrVmNotReady = fmt.Errorf("VM not ready") ) -// MakeVmToLargeForHostErr creates a VmTooLargeForHostErr with the available CPU and RAM +// MakeVmToLargeForHostErr creates a ErrVmToLargeForHost with the available CPU and RAM func MakeVmToLargeForHostErr(cpuAvailable, ramAvailable int) error { - return fmt.Errorf("%w. There is only %d CPU cores and %d GB RAM available on the host", VmTooLargeForHostErr, cpuAvailable, ramAvailable) + return fmt.Errorf("%w. There is only %d CPU cores and %d GB RAM available on the host", ErrVmToLargeForHost, cpuAvailable, ramAvailable) } diff --git a/routers/api/v2/gpu_group.go b/routers/api/v2/gpu_group.go index 9ba65673..84d46797 100644 --- a/routers/api/v2/gpu_group.go +++ b/routers/api/v2/gpu_group.go @@ -36,7 +36,7 @@ func GetGpuGroup(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -44,7 +44,7 @@ func GetGpuGroup(c *gin.Context) { gpuGroup, err := deployV2.VMs().GpuGroups().Get(requestURI.GpuGroupID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -57,7 +57,7 @@ func GetGpuGroup(c *gin.Context) { GpuGroupID: &gpuGroup.ID, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -96,7 +96,7 @@ func ListGpuGroups(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -106,7 +106,7 @@ func ListGpuGroups(c *gin.Context) { Pagination: utils.GetOrDefaultPagination(requestQuery.Pagination), }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -121,7 +121,7 @@ func ListGpuGroups(c *gin.Context) { GpuGroupID: &gpuGroup.ID, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/gpu_lease.go b/routers/api/v2/gpu_lease.go index fc9b715d..694d5403 100644 --- a/routers/api/v2/gpu_lease.go +++ b/routers/api/v2/gpu_lease.go @@ -42,13 +42,13 @@ func GetGpuLease(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } gpuLease, err := service.V2(auth).VMs().GpuLeases().Get(requestURI.GpuLeaseID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -59,11 +59,11 @@ func GetGpuLease(c *gin.Context) { position, err := service.V2(auth).VMs().GpuLeases().GetQueuePosition(gpuLease.ID) if err != nil { - if errors.Is(err, sErrors.GpuLeaseNotFoundErr) { + if errors.Is(err, sErrors.ErrGpuLeaseNotFound) { position = -1 } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) } context.Ok(gpuLease.ToDTO(position)) @@ -103,7 +103,7 @@ func ListGpuLeases(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -117,7 +117,7 @@ func ListGpuLeases(c *gin.Context) { UserID: userID, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -131,9 +131,9 @@ func ListGpuLeases(c *gin.Context) { queuePosition, err := service.V2(auth).VMs().GpuLeases().GetQueuePosition(gpuLease.ID) if err != nil { switch { - case errors.Is(err, sErrors.GpuLeaseNotFoundErr): + case errors.Is(err, sErrors.ErrGpuLeaseNotFound): continue - case errors.Is(err, sErrors.GpuGroupNotFoundErr): + case errors.Is(err, sErrors.ErrGpuGroupNotFound): continue } @@ -177,7 +177,7 @@ func CreateGpuLease(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -191,7 +191,7 @@ func CreateGpuLease(c *gin.Context) { groupExists, err := deployV2.VMs().GpuGroups().Exists(requestBody.GpuGroupID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -206,7 +206,7 @@ func CreateGpuLease(c *gin.Context) { }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -224,7 +224,7 @@ func CreateGpuLease(c *gin.Context) { "authInfo": auth, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -266,7 +266,7 @@ func UpdateGpuLease(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -274,7 +274,7 @@ func UpdateGpuLease(c *gin.Context) { gpuLease, err := deployV2.VMs().GpuLeases().Get(requestURI.GpuLeaseID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -296,7 +296,7 @@ func UpdateGpuLease(c *gin.Context) { "authInfo": auth, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -331,7 +331,7 @@ func DeleteGpuLease(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -339,7 +339,7 @@ func DeleteGpuLease(c *gin.Context) { gpuLease, err := deployV2.VMs().GpuLeases().Get(requestURI.GpuLeaseID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -354,7 +354,7 @@ func DeleteGpuLease(c *gin.Context) { "authInfo": auth, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/job.go b/routers/api/v2/job.go index 94592ba0..52ad96bb 100644 --- a/routers/api/v2/job.go +++ b/routers/api/v2/job.go @@ -42,13 +42,13 @@ func GetJob(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } job, err := service.V2(auth).Jobs().Get(requestURI.JobID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -87,7 +87,7 @@ func ListJobs(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -102,7 +102,7 @@ func ListJobs(c *gin.Context) { ExcludeStatus: requestQuery.ExcludeStatus, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -148,23 +148,23 @@ func UpdateJob(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } updated, err := service.V2(auth).Jobs().Update(requestURI.JobID, &request) if err != nil { - if errors.Is(err, sErrors.ForbiddenErr) { + if errors.Is(err, sErrors.ErrForbidden) { context.Forbidden("User is not allowed to update jobs") return } - if errors.Is(err, sErrors.JobNotFoundErr) { + if errors.Is(err, sErrors.ErrJobNotFound) { context.NotFound("Job not found") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/middleware/access_gpu_routes.go b/routers/api/v2/middleware/access_gpu_routes.go index 0457d51f..55040ad6 100644 --- a/routers/api/v2/middleware/access_gpu_routes.go +++ b/routers/api/v2/middleware/access_gpu_routes.go @@ -1,11 +1,12 @@ package middleware import ( + "net/http" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/pkg/app/status_codes" "github.com/kthcloud/go-deploy/pkg/sys" v2 "github.com/kthcloud/go-deploy/routers/api/v2" - "net/http" ) // AccessGpuRoutes is a middleware that checks if the user has access to the GPU routes. @@ -16,7 +17,7 @@ func AccessGpuRoutes() func(c *gin.Context) { auth, err := v2.WithAuth(&context) if err != nil { - context.ServerError(err, v2.AuthInfoNotAvailableErr) + context.ServerError(err, v2.ErrAuthInfoNotAvailable) c.Abort() } diff --git a/routers/api/v2/middleware/synchronize_user.go b/routers/api/v2/middleware/synchronize_user.go index b018ff0b..33d99d9b 100644 --- a/routers/api/v2/middleware/synchronize_user.go +++ b/routers/api/v2/middleware/synchronize_user.go @@ -2,6 +2,7 @@ package middleware import ( "fmt" + "github.com/gin-gonic/gin" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -26,14 +27,14 @@ func SetupAuthUser(c *gin.Context) { case context.HasApiKey(): apiKey, err := context.GetApiKey() if err != nil { - context.ServerError(err, v2.AuthInfoSetupFailedErr) + context.ServerError(err, v2.ErrAuthInfoSetupFailed) c.Abort() return } user, err = service.V2().Users().GetByApiKey(apiKey) if err != nil { - context.ServerError(err, v2.AuthInfoSetupFailedErr) + context.ServerError(err, v2.ErrAuthInfoSetupFailed) c.Abort() return } @@ -46,7 +47,7 @@ func SetupAuthUser(c *gin.Context) { case context.HasKeycloakToken(): jwtToken, err := context.GetKeycloakToken() if err != nil { - context.ServerError(err, v2.InternalError) + context.ServerError(err, v2.ErrInternal) c.Abort() return } @@ -71,20 +72,20 @@ func SetupAuthUser(c *gin.Context) { user, err = service.V2().Users().Synchronize(authParams) if err != nil { - context.ServerError(err, v2.AuthInfoSetupFailedErr) + context.ServerError(err, v2.ErrAuthInfoSetupFailed) c.Abort() return } if user == nil { - context.ServerError(fmt.Errorf("failed to synchronize auth user"), v2.AuthInfoSetupFailedErr) + context.ServerError(fmt.Errorf("failed to synchronize auth user"), v2.ErrAuthInfoSetupFailed) c.Abort() return } } if user == nil { - context.ServerError(fmt.Errorf("failed to synchronize auth user"), v2.AuthInfoSetupFailedErr) + context.ServerError(fmt.Errorf("failed to synchronize auth user"), v2.ErrAuthInfoSetupFailed) c.Abort() return } diff --git a/routers/api/v2/notification.go b/routers/api/v2/notification.go index a5e2dc51..27f2fc03 100644 --- a/routers/api/v2/notification.go +++ b/routers/api/v2/notification.go @@ -38,13 +38,13 @@ func GetNotification(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } notification, err := service.V2(auth).Notifications().Get(requestQuery.NotificationID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -77,7 +77,7 @@ func ListNotifications(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -93,7 +93,7 @@ func ListNotifications(c *gin.Context) { UserID: userID, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -135,13 +135,13 @@ func UpdateNotification(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } updated, err := service.V2(auth).Notifications().Update(requestQuery.NotificationID, &requestBody) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -176,18 +176,18 @@ func DeleteNotification(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } err = service.V2(auth).Notifications().Delete(requestQuery.NotificationID) if err != nil { - if errors.Is(err, sErrors.NotificationNotFoundErr) { + if errors.Is(err, sErrors.ErrNotificationNotFound) { context.NotFound("Notification not found") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/register.go b/routers/api/v2/register.go index ebcb28cb..9cb1828b 100644 --- a/routers/api/v2/register.go +++ b/routers/api/v2/register.go @@ -31,13 +31,13 @@ func Register(c *gin.Context) { err = service.V2().System().RegisterNode(&requestQueryJoin) if err != nil { switch { - case errors.Is(err, sErrors.BadDiscoveryTokenErr): + case errors.Is(err, sErrors.ErrBadDiscoveryToken): context.UserError("Invalid token") return - case errors.Is(err, sErrors.ZoneNotFoundErr): + case errors.Is(err, sErrors.ErrZoneNotFound): context.NotFound("Zone not found") return - case errors.Is(err, sErrors.HostNotFoundErr): + case errors.Is(err, sErrors.ErrHostNotFound): context.NotFound("Host not found") return } diff --git a/routers/api/v2/resource_migration.go b/routers/api/v2/resource_migration.go index fc89dcb4..456fca12 100644 --- a/routers/api/v2/resource_migration.go +++ b/routers/api/v2/resource_migration.go @@ -39,13 +39,13 @@ func GetResourceMigration(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } resourceMigration, err := service.V2(auth).ResourceMigrations().Get(requestQuery.ResourceMigrationID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -82,13 +82,13 @@ func ListResourceMigrations(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } resourceMigrations, err := service.V2(auth).ResourceMigrations().List() if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -130,7 +130,7 @@ func CreateResourceMigration(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -139,30 +139,30 @@ func CreateResourceMigration(c *gin.Context) { resourceMigration, jobID, err := deployV2.ResourceMigrations().Create(uuid.New().String(), auth.User.ID, &requestBody) if err != nil { switch { - case errors.Is(err, sErrors.ResourceMigrationAlreadyExistsErr): + case errors.Is(err, sErrors.ErrResourceMigrationAlreadyExists): context.UserError("Resource migration already exists") return - case errors.Is(err, sErrors.BadResourceMigrationParamsErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationParams): context.UserError("Bad resource migration params") return - case errors.Is(err, sErrors.BadResourceMigrationStatusErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationStatus): context.UserError("Bad resource migration status") return - case errors.Is(err, sErrors.BadResourceMigrationTypeErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationType): context.UserError("Bad resource migration type") return - case errors.Is(err, sErrors.BadResourceMigrationResourceTypeErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationResourceType): context.UserError("Bad resource migration resource type") return - case errors.Is(err, sErrors.ResourceNotFoundErr): + case errors.Is(err, sErrors.ErrResourceNotFound): context.UserError("Resource not found") return - case errors.Is(err, sErrors.AlreadyMigratedErr): + case errors.Is(err, sErrors.ErrAlreadyMigrated): context.UserError("Resource already migrated") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -204,7 +204,7 @@ func UpdateResourceMigration(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -214,7 +214,7 @@ func UpdateResourceMigration(c *gin.Context) { MigrationCode: requestBody.Code, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -229,36 +229,36 @@ func UpdateResourceMigration(c *gin.Context) { }) if err != nil { switch { - case errors.Is(err, sErrors.ResourceMigrationNotFoundErr): + case errors.Is(err, sErrors.ErrResourceMigrationNotFound): context.NotFound("Resource migration not found") return - case errors.Is(err, sErrors.AlreadyAcceptedErr): + case errors.Is(err, sErrors.ErrAlreadyAccepted): context.UserError("Resource migration already accepted") return - case errors.Is(err, sErrors.AlreadyMigratedErr): + case errors.Is(err, sErrors.ErrAlreadyMigrated): context.UserError("Resource already migrated") return - case errors.Is(err, sErrors.BadResourceMigrationParamsErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationParams): context.UserError("Bad resource migration params") return - case errors.Is(err, sErrors.BadResourceMigrationStatusErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationStatus): context.UserError("Bad resource migration status") return - case errors.Is(err, sErrors.BadResourceMigrationTypeErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationType): context.UserError("Bad resource migration type") return - case errors.Is(err, sErrors.BadResourceMigrationResourceTypeErr): + case errors.Is(err, sErrors.ErrBadResourceMigrationResourceType): context.UserError("Bad resource migration resource type") return - case errors.Is(err, sErrors.ResourceNotFoundErr): + case errors.Is(err, sErrors.ErrResourceNotFound): context.UserError("Resource not found") return - case errors.Is(err, sErrors.BadMigrationCodeErr): + case errors.Is(err, sErrors.ErrBadMigrationCode): context.UserError("Bad migration code") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -298,7 +298,7 @@ func DeleteResourceMigration(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -306,7 +306,7 @@ func DeleteResourceMigration(c *gin.Context) { resourceMigration, err := deployV2.ResourceMigrations().Get(requestQuery.ResourceMigrationID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -317,12 +317,12 @@ func DeleteResourceMigration(c *gin.Context) { err = deployV2.ResourceMigrations().Delete(resourceMigration.ID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/sm.go b/routers/api/v2/sm.go index 38b5ee24..d334556f 100644 --- a/routers/api/v2/sm.go +++ b/routers/api/v2/sm.go @@ -45,7 +45,7 @@ func GetSM(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -89,7 +89,7 @@ func ListSMs(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -99,7 +99,7 @@ func ListSMs(c *gin.Context) { }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -141,7 +141,7 @@ func DeleteSM(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -149,7 +149,7 @@ func DeleteSM(c *gin.Context) { sm, err := deployV2.SMs().Get(requestURI.SmID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -164,7 +164,7 @@ func DeleteSM(c *gin.Context) { "ownerId": sm.OwnerID, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/system.go b/routers/api/v2/system.go index 9d1c2b12..2ca9674c 100644 --- a/routers/api/v2/system.go +++ b/routers/api/v2/system.go @@ -30,7 +30,7 @@ func ListSystemCapacities(c *gin.Context) { capacities, err := service.V2().System().ListCapacities(requestQuery.N) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -63,7 +63,7 @@ func ListSystemStats(c *gin.Context) { stats, err := service.V2().System().ListStats(requestQuery.N) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -96,7 +96,7 @@ func ListSystemStatus(c *gin.Context) { status, err := service.V2().System().ListStatus(requestQuery.N) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/team.go b/routers/api/v2/team.go index 6ba3bff5..f312dde5 100644 --- a/routers/api/v2/team.go +++ b/routers/api/v2/team.go @@ -47,13 +47,13 @@ func GetTeam(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } team, err := service.V2(auth).Teams().Get(requestURI.TeamID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -87,7 +87,7 @@ func ListTeams(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -103,7 +103,7 @@ func ListTeams(c *gin.Context) { UserID: userID, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -139,18 +139,18 @@ func CreateTeam(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } team, err := service.V2(auth).Teams().Create(uuid.NewString(), auth.User.ID, &requestQuery) if err != nil { - if errors.Is(err, sErrors.TeamNameTakenErr) { + if errors.Is(err, sErrors.ErrTeamNameTaken) { context.UserError("Team name is taken") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -194,18 +194,18 @@ func UpdateTeam(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } updated, err := service.V2(auth).Teams().Update(requestURI.TeamID, &requestQuery) if err != nil { - if errors.Is(err, sErrors.TeamNameTakenErr) { + if errors.Is(err, sErrors.ErrTeamNameTaken) { context.UserError("Team name is taken") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -241,18 +241,18 @@ func DeleteTeam(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } err = service.V2(auth).Teams().Delete(requestURI.TeamID) if err != nil { - if errors.Is(err, sErrors.TeamNotFoundErr) { + if errors.Is(err, sErrors.ErrTeamNotFound) { context.NotFound("Team not found") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -264,22 +264,22 @@ func DeleteTeam(c *gin.Context) { func joinTeam(context sys.ClientContext, id string, requestBody *body.TeamJoin) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) } team, err := service.V2(auth).Teams().Join(id, requestBody) if err != nil { - if errors.Is(err, sErrors.NotInvitedErr) { + if errors.Is(err, sErrors.ErrNotInvited) { context.UserError("User not invited to team") return } - if errors.Is(err, sErrors.BadInviteCodeErr) { + if errors.Is(err, sErrors.ErrBadInviteCode) { context.Forbidden("Bad invite code") return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/user.go b/routers/api/v2/user.go index 9a2e47aa..e863879a 100644 --- a/routers/api/v2/user.go +++ b/routers/api/v2/user.go @@ -47,7 +47,7 @@ func GetUser(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -62,7 +62,7 @@ func GetUser(c *gin.Context) { UserID: &requestURI.UserID, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -77,7 +77,7 @@ func GetUser(c *gin.Context) { user, err := deployV2.Users().Get(requestURI.UserID) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -122,7 +122,7 @@ func ListUsers(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -134,7 +134,7 @@ func ListUsers(c *gin.Context) { Pagination: sUtils.GetOrDefaultPagination(requestQuery.Pagination), }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -153,7 +153,7 @@ func ListUsers(c *gin.Context) { All: requestQuery.All, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -198,7 +198,7 @@ func UpdateUser(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -213,11 +213,11 @@ func UpdateUser(c *gin.Context) { updated, err := deployV2.Users().Update(requestURI.UserID, &userUpdate) if err != nil { switch { - case errors.Is(err, sErrors.UserNotFoundErr): + case errors.Is(err, sErrors.ErrUserNotFound): context.NotFound("User not found") } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -226,6 +226,6 @@ func UpdateUser(c *gin.Context) { return } - usage, err := deployV2.Users().GetUsage(updated.ID) + usage, _ := deployV2.Users().GetUsage(updated.ID) context.JSONResponse(200, updated.ToDTO(effectiveRole, usage, deployV2.SMs().GetUrlByUserID(updated.ID))) } diff --git a/routers/api/v2/vm.go b/routers/api/v2/vm.go index 962c3900..c0a490c8 100644 --- a/routers/api/v2/vm.go +++ b/routers/api/v2/vm.go @@ -52,7 +52,7 @@ func GetVM(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -66,7 +66,7 @@ func GetVM(c *gin.Context) { } if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -110,7 +110,7 @@ func ListVMs(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -129,7 +129,7 @@ func ListVMs(c *gin.Context) { Shared: true, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -175,7 +175,7 @@ func CreateVM(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -183,7 +183,7 @@ func CreateVM(c *gin.Context) { unique, err := deployV2.VMs().NameAvailable(requestBody.Name) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -218,7 +218,7 @@ func CreateVM(c *gin.Context) { return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -231,7 +231,7 @@ func CreateVM(c *gin.Context) { "authInfo": auth, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -267,7 +267,7 @@ func DeleteVM(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -275,7 +275,7 @@ func DeleteVM(c *gin.Context) { vm, err := deployV2.VMs().Get(requestURI.VmID, opts.GetOpts{Shared: true}) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -295,7 +295,7 @@ func DeleteVM(c *gin.Context) { "authInfo": auth, }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -338,7 +338,7 @@ func UpdateVM(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -346,7 +346,7 @@ func UpdateVM(c *gin.Context) { vm, err := deployV2.VMs().Get(requestURI.VmID, opts.GetOpts{Shared: true}) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -358,7 +358,7 @@ func UpdateVM(c *gin.Context) { if requestBody.Name != nil { available, err := deployV2.VMs().NameAvailable(*requestBody.Name) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -394,7 +394,7 @@ func UpdateVM(c *gin.Context) { return } - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -406,7 +406,7 @@ func UpdateVM(c *gin.Context) { }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/vm_action.go b/routers/api/v2/vm_action.go index f6bf859c..05cbf314 100644 --- a/routers/api/v2/vm_action.go +++ b/routers/api/v2/vm_action.go @@ -44,7 +44,7 @@ func CreateVmAction(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } @@ -52,7 +52,7 @@ func CreateVmAction(c *gin.Context) { vm, err := deployV2.VMs().Get(requestQuery.VmID, opts.GetOpts{Shared: true}) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } @@ -74,7 +74,7 @@ func CreateVmAction(c *gin.Context) { }) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/worker_status.go b/routers/api/v2/worker_status.go index c8d91777..4e23fcac 100644 --- a/routers/api/v2/worker_status.go +++ b/routers/api/v2/worker_status.go @@ -29,7 +29,7 @@ func ListWorkerStatus(c *gin.Context) { workerStatus, err := service.V2().System().ListWorkerStatus(opts.ListWorkerStatusOpts{}) if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/v2/zone.go b/routers/api/v2/zone.go index 7953da13..aed20524 100644 --- a/routers/api/v2/zone.go +++ b/routers/api/v2/zone.go @@ -30,13 +30,13 @@ func ListZones(c *gin.Context) { auth, err := WithAuth(&context) if err != nil { - context.ServerError(err, AuthInfoNotAvailableErr) + context.ServerError(err, ErrAuthInfoNotAvailable) return } zoneList, err := service.V2(auth).System().ListZones() if err != nil { - context.ServerError(err, InternalError) + context.ServerError(err, ErrInternal) return } diff --git a/routers/api/validators/validators.go b/routers/api/validators/validators.go index 4e798bb5..2cafc3c9 100644 --- a/routers/api/validators/validators.go +++ b/routers/api/validators/validators.go @@ -1,14 +1,15 @@ package validators import ( + "regexp" + "strings" + "time" + "github.com/go-playground/validator/v10" bodyV2 "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/config" "golang.org/x/crypto/ssh" "golang.org/x/net/idna" - "regexp" - "strings" - "time" ) // Rfc1035 is a validator for RFC 1035 hostnames @@ -32,10 +33,7 @@ func SshPublicKey(fl validator.FieldLevel) bool { } _, _, _, _, err := ssh.ParseAuthorizedKey([]byte(publicKey)) - if err != nil { - return false - } - return true + return err == nil } // EnvName is a validator for environment variable names diff --git a/routers/router.go b/routers/router.go index d57fc673..1a3914c2 100644 --- a/routers/router.go +++ b/routers/router.go @@ -172,9 +172,7 @@ func getUrlBasePath() string { res = u.Path // Remove trailing slash - if strings.HasSuffix(res, "/") { - res = strings.TrimSuffix(res, "/") - } + res = strings.TrimSuffix(res, "/") return res } diff --git a/scripts/check-lint.sh b/scripts/check-lint.sh index 9e2a02a1..1caa646f 100755 --- a/scripts/check-lint.sh +++ b/scripts/check-lint.sh @@ -58,7 +58,7 @@ function run_go_vet() { function run_go_cyclo() { echo -e "${YELLOW}Running go-cyclo check...${NC}" # Check for cyclomatic complexity - go_cyclo_output=$(gocyclo -over 15 .) + go_cyclo_output=$(find . -path ./pkg/imp -prune -o -type f -name "*.go" -exec gocyclo -over 15 {} +) if [ -n "$go_cyclo_output" ]; then echo -e "${RED}gocyclo found the following issues:${NC}" echo "$go_cyclo_output" diff --git a/service/errors/errors.go b/service/errors/errors.go index d1939cb4..428c6665 100644 --- a/service/errors/errors.go +++ b/service/errors/errors.go @@ -51,135 +51,135 @@ func NewZoneCapabilityMissingError(zone, capability string) ZoneCapabilityMissin } var ( - // AuthInfoNotAvailableErr is returned when the auth info is not available - AuthInfoNotAvailableErr = fmt.Errorf("auth info not available") + // ErrAuthInfoNotAvailable is returned when the auth info is not available + ErrAuthInfoNotAvailable = fmt.Errorf("auth info not available") - // BadDiscoveryTokenErr is returned when the discovery token is invalid. - BadDiscoveryTokenErr = fmt.Errorf("bad discovery token") + // ErrBadDiscoveryToken is returned when the discovery token is invalid. + ErrBadDiscoveryToken = fmt.Errorf("bad discovery token") - // DeploymentNotFoundErr is returned when the deployment is not found. + // ErrDeploymentNotFound is returned when the deployment is not found. // This is most likely caused by a race-condition between a some model call and a deletion call. - DeploymentNotFoundErr = fmt.Errorf("deployment not found") + ErrDeploymentNotFound = fmt.Errorf("deployment not found") - // DeploymentHasNotCiConfigErr is returned when the deployment does not have a CI config. - DeploymentHasNotCiConfigErr = fmt.Errorf("deployment does not have a CI config") + // ErrDeploymentHasNoCiConfig is returned when the deployment does not have a CI config. + ErrDeploymentHasNoCiConfig = fmt.Errorf("deployment does not have a CI config") - // MainAppNotFoundErr is returned when the main app is not found. + // ErrMainAppNotFound is returned when the main app is not found. // This could be caused by stale data in the database. - MainAppNotFoundErr = fmt.Errorf("main app not found") + ErrMainAppNotFound = fmt.Errorf("main app not found") - // IngressHostInUseErr is returned when the ingress host is already in use. - IngressHostInUseErr = fmt.Errorf("ingress host already in use") + // ErrIngressHostInUse is returned when the ingress host is already in use. + ErrIngressHostInUse = fmt.Errorf("ingress host already in use") - // SmNotFoundErr is returned when the storage manager is not found. - SmNotFoundErr = fmt.Errorf("storage manager not found") + // ErrSmNotFound is returned when the storage manager is not found. + ErrSmNotFound = fmt.Errorf("storage manager not found") - // SmAlreadyExistsErr is returned when the storage manager already exists for user. - SmAlreadyExistsErr = fmt.Errorf("storage manager already exists for user") + // ErrSmAlreadyExists is returned when the storage manager already exists for user. + ErrSmAlreadyExists = fmt.Errorf("storage manager already exists for user") - // VmNotFoundErr is returned when the vm is not found. + // ErrVmNotFound is returned when the vm is not found. // This is most likely caused by a race-condition between a some model call and a deletion call. - VmNotFoundErr = fmt.Errorf("vm not found") + ErrVmNotFound = fmt.Errorf("vm not found") - // GpuNotFoundErr is returned when the gpu is not found. - GpuNotFoundErr = fmt.Errorf("gpu not found") + // ErrGpuNotFound is returned when the gpu is not found. + ErrGpuNotFound = fmt.Errorf("gpu not found") - // GpuLeaseAlreadyExistsErr is returned when a GPU lease already exists for a user. - GpuLeaseAlreadyExistsErr = fmt.Errorf("gpu lease already exists") + // ErrGpuLeaseAlreadyExists is returned when a GPU lease already exists for a user. + ErrGpuLeaseAlreadyExists = fmt.Errorf("gpu lease already exists") - // GpuLeaseNotActiveErr is returned when the GPU lease is not active. - GpuLeaseNotActiveErr = fmt.Errorf("gpu lease not active") + // ErrGpuLeaseNotActive is returned when the GPU lease is not active. + ErrGpuLeaseNotActive = fmt.Errorf("gpu lease not active") - // GpuLeaseNotAssignedErr is returned when the GPU lease is not assigned. - GpuLeaseNotAssignedErr = fmt.Errorf("gpu lease not assigned") + // ErrGpuLeaseNotAssigned is returned when the GPU lease is not assigned. + ErrGpuLeaseNotAssigned = fmt.Errorf("gpu lease not assigned") - // GpuLeaseNotFoundErr is returned when the GPU lease is not found. - GpuLeaseNotFoundErr = fmt.Errorf("gpu lease not found") + // ErrGpuLeaseNotFound is returned when the GPU lease is not found. + ErrGpuLeaseNotFound = fmt.Errorf("gpu lease not found") - // VmAlreadyAttachedErr is returned when a VM is already attached to a GPU lease. - VmAlreadyAttachedErr = fmt.Errorf("vm already attached") + // ErrVmAlreadyAttached is returned when a VM is already attached to a GPU lease. + ErrVmAlreadyAttached = fmt.Errorf("vm already attached") - // GpuGroupNotFoundErr is returned when the GPU group is not found. - GpuGroupNotFoundErr = fmt.Errorf("gpu group not found") + // ErrGpuGroupNotFound is returned when the GPU group is not found. + ErrGpuGroupNotFound = fmt.Errorf("gpu group not found") - // NoPortsAvailableErr is returned when there are no ports available. - NoPortsAvailableErr = fmt.Errorf("no ports available") + // ErrNoPortsAvailable is returned when there are no ports available. + ErrNoPortsAvailable = fmt.Errorf("no ports available") - // ZoneNotFoundErr is returned when the zone is not found. + // ErrZoneNotFound is returned when the zone is not found. // This could be caused by stale data in the database. - ZoneNotFoundErr = fmt.Errorf("zone not found") + ErrZoneNotFound = fmt.Errorf("zone not found") - // HostNotFoundErr is returned when the host is not found. + // ErrHostNotFound is returned when the host is not found. // This could be caused by stale data in the database or inconsistent state of the system/cluster. - HostNotFoundErr = fmt.Errorf("host not found") + ErrHostNotFound = fmt.Errorf("host not found") - // SnapshotNotFoundErr is returned when the snapshot is not found. - SnapshotNotFoundErr = fmt.Errorf("snapshot not found") + // ErrSnapshotNotFound is returned when the snapshot is not found. + ErrSnapshotNotFound = fmt.Errorf("snapshot not found") - // NonUniqueFieldErr is returned when a field is not unique, such as the name of a deployment. - NonUniqueFieldErr = fmt.Errorf("non unique field") + // ErrNonUniqueField is returned when a field is not unique, such as the name of a deployment. + ErrNonUniqueField = fmt.Errorf("non unique field") - // TeamNameTakenErr is returned when the team name is already taken by another team. + // ErrTeamNameTaken is returned when the team name is already taken by another team. // Every team name should be unique. - TeamNameTakenErr = fmt.Errorf("team name taken") + ErrTeamNameTaken = fmt.Errorf("team name taken") - // TeamNotFoundErr is returned when the team is not found. - TeamNotFoundErr = fmt.Errorf("team not found") + // ErrTeamNotFound is returned when the team is not found. + ErrTeamNotFound = fmt.Errorf("team not found") - // UserNotFoundErr is returned when the user is not found. - UserNotFoundErr = fmt.Errorf("user not found") + // ErrUserNotFound is returned when the user is not found. + ErrUserNotFound = fmt.Errorf("user not found") - // ApiKeyNameTakenErr is returned when the API key name is already taken by another API key. + // ErrApiKeyNameTaken is returned when the API key name is already taken by another API key. // Every API key name should be unique. - ApiKeyNameTakenErr = fmt.Errorf("api key name taken") + ErrApiKeyNameTaken = fmt.Errorf("api key name taken") - // BadInviteCodeErr is returned when the invite code is invalid. - BadInviteCodeErr = fmt.Errorf("bad invite code") + // ErrBadInviteCode is returned when the invite code is invalid. + ErrBadInviteCode = fmt.Errorf("bad invite code") - // NotInvitedErr is returned when the user tries to join a team, but is not invited. - NotInvitedErr = fmt.Errorf("not invited") + // ErrNotInvited is returned when the user tries to join a team, but is not invited. + ErrNotInvited = fmt.Errorf("not invited") - // ForbiddenErr is returned when the user is not allowed to perform an action. - ForbiddenErr = fmt.Errorf("forbidden") + // ErrForbidden is returned when the user is not allowed to perform an action. + ErrForbidden = fmt.Errorf("forbidden") - // JobNotFoundErr is returned when the job is not found. - JobNotFoundErr = fmt.Errorf("job not found") + // ErrJobNotFound is returned when the job is not found. + ErrJobNotFound = fmt.Errorf("job not found") - // NotificationNotFoundErr is returned when the notification is not found. - NotificationNotFoundErr = fmt.Errorf("notification not found") + // ErrNotificationNotFound is returned when the notification is not found. + ErrNotificationNotFound = fmt.Errorf("notification not found") - // ResourceMigrationNotFoundErr is returned when the resource migration is not found. - ResourceMigrationNotFoundErr = fmt.Errorf("resource migration not found") + // ErrResourceMigrationNotFound is returned when the resource migration is not found. + ErrResourceMigrationNotFound = fmt.Errorf("resource migration not found") - // AlreadyAcceptedErr is returned when the resource migration is already accepted. - AlreadyAcceptedErr = fmt.Errorf("resource migration already accepted") + // ErrAlreadyAccepted is returned when the resource migration is already accepted. + ErrAlreadyAccepted = fmt.Errorf("resource migration already accepted") - // AlreadyMigratedErr is returned when the resource is already migrated. - AlreadyMigratedErr = fmt.Errorf("resource already migrated") + // ErrAlreadyMigrated is returned when the resource is already migrated. + ErrAlreadyMigrated = fmt.Errorf("resource already migrated") - // ResourceMigrationAlreadyExistsErr is returned when the resource migration already exists. - ResourceMigrationAlreadyExistsErr = fmt.Errorf("resource migration already exists") + // ErrResourceMigrationAlreadyExists is returned when the resource migration already exists. + ErrResourceMigrationAlreadyExists = fmt.Errorf("resource migration already exists") - // BadResourceMigrationTypeErr is returned when the resource migration type is invalid. + // ErrBadResourceMigrationType is returned when the resource migration type is invalid. // This could be caused by providing another type than what is expected by the function. - BadResourceMigrationTypeErr = fmt.Errorf("bad resource migration type") + ErrBadResourceMigrationType = fmt.Errorf("bad resource migration type") - // BadResourceMigrationResourceTypeErr is returned when the resource migration resource type is invalid. + // ErrBadResourceMigrationResourceType is returned when the resource migration resource type is invalid. // This could be caused by providing another type than what is expected by the function. - BadResourceMigrationResourceTypeErr = fmt.Errorf("bad resource migration resource type") + ErrBadResourceMigrationResourceType = fmt.Errorf("bad resource migration resource type") - // BadResourceMigrationParamsErr is returned when the resource migration params are invalid. + // ErrBadResourceMigrationParamsErr is returned when the resource migration params are invalid. // This could be caused by providing another type than what is expected by the function. - BadResourceMigrationParamsErr = fmt.Errorf("bad resource migration params") + ErrBadResourceMigrationParams = fmt.Errorf("bad resource migration params") - // BadResourceMigrationStatusErr is returned when the resource migration status is invalid. + // ErrBadResourceMigrationStatus is returned when the resource migration status is invalid. // This could be caused by providing another type than what is expected by the function. - BadResourceMigrationStatusErr = fmt.Errorf("bad resource migration status") + ErrBadResourceMigrationStatus = fmt.Errorf("bad resource migration status") - // ResourceNotFoundErr is returned when the resource is not found. + // ErrResourceNotFound is returned when the resource is not found. // This is used when the type of resource is unknown, such as for team resources or migration resources. - ResourceNotFoundErr = fmt.Errorf("resource not found") + ErrResourceNotFound = fmt.Errorf("resource not found") - // BadMigrationCodeErr is returned when the migration code is invalid. - BadMigrationCodeErr = fmt.Errorf("bad migration code") + // ErrBadMigrationCode is returned when the migration code is invalid. + ErrBadMigrationCode = fmt.Errorf("bad migration code") ) diff --git a/service/v2/deployments/ci_config_service.go b/service/v2/deployments/ci_config_service.go index 88df13e0..e2d34d7e 100644 --- a/service/v2/deployments/ci_config_service.go +++ b/service/v2/deployments/ci_config_service.go @@ -2,6 +2,8 @@ package deployments import ( "fmt" + "strings" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -9,7 +11,6 @@ import ( "github.com/kthcloud/go-deploy/service/v2/deployments/opts" "github.com/kthcloud/go-deploy/utils/subsystemutils" "gopkg.in/yaml.v3" - "strings" ) // GetCiConfig returns the CI config for the deployment. @@ -23,7 +24,7 @@ func (c *Client) GetCiConfig(id string) (*body.CiConfig, error) { } if deployment == nil { - return nil, errors.DeploymentNotFoundErr + return nil, errors.ErrDeploymentNotFound } if !deployment.Ready() { @@ -31,7 +32,7 @@ func (c *Client) GetCiConfig(id string) (*body.CiConfig, error) { } if deployment.Type != model.DeploymentTypeCustom { - return nil, errors.DeploymentHasNotCiConfigErr + return nil, errors.ErrDeploymentHasNoCiConfig } tag := fmt.Sprintf("%s/%s/%s", diff --git a/service/v2/deployments/deployment_service.go b/service/v2/deployments/deployment_service.go index 3bafb463..3f5c377a 100644 --- a/service/v2/deployments/deployment_service.go +++ b/service/v2/deployments/deployment_service.go @@ -253,8 +253,8 @@ func (c *Client) Create(id, ownerID string, deploymentCreate *body.DeploymentCre deployment, err := deployment_repo.New().Create(id, ownerID, params) if err != nil { - if errors.Is(err, rErrors.NonUniqueFieldErr) { - return sErrors.NonUniqueFieldErr + if errors.Is(err, rErrors.ErrNonUniqueField) { + return sErrors.ErrNonUniqueField } return makeError(err) @@ -276,7 +276,7 @@ func (c *Client) Create(id, ownerID string, deploymentCreate *body.DeploymentCre } } - deployment, err = c.Refresh(id) + _, err = c.Refresh(id) if err != nil { return makeError(err) } @@ -303,12 +303,12 @@ func (c *Client) Update(id string, dtoUpdate *body.DeploymentUpdate) error { } if d == nil { - return sErrors.DeploymentNotFoundErr + return sErrors.ErrDeploymentNotFound } mainApp := d.GetMainApp() if mainApp == nil { - return makeError(sErrors.MainAppNotFoundErr) + return makeError(sErrors.ErrMainAppNotFound) } params := &model.DeploymentUpdateParams{} @@ -326,8 +326,8 @@ func (c *Client) Update(id string, dtoUpdate *body.DeploymentUpdate) error { err = deployment_repo.New().UpdateWithParams(id, params) if err != nil { - if errors.Is(err, rErrors.NonUniqueFieldErr) { - return sErrors.NonUniqueFieldErr + if errors.Is(err, rErrors.ErrNonUniqueField) { + return sErrors.ErrNonUniqueField } return makeError(err) @@ -345,7 +345,7 @@ func (c *Client) Update(id string, dtoUpdate *body.DeploymentUpdate) error { } } - d, err = c.Refresh(id) + _, err = c.Refresh(id) if err != nil { return makeError(err) } @@ -374,7 +374,7 @@ func (c *Client) UpdateOwner(id string, params *model.DeploymentUpdateOwnerParam } if d == nil { - return sErrors.DeploymentNotFoundErr + return sErrors.ErrDeploymentNotFound } var newImage *string @@ -391,7 +391,7 @@ func (c *Client) UpdateOwner(id string, params *model.DeploymentUpdateOwnerParam return makeError(err) } - d, err = c.Refresh(id) + _, err = c.Refresh(id) if err != nil { return makeError(err) } @@ -401,7 +401,7 @@ func (c *Client) UpdateOwner(id string, params *model.DeploymentUpdateOwnerParam return makeError(err) } - d, err = c.Refresh(id) + _, err = c.Refresh(id) if err != nil { return makeError(err) } @@ -434,7 +434,7 @@ func (c *Client) Delete(id string) error { } if d == nil { - return sErrors.DeploymentNotFoundErr + return sErrors.ErrDeploymentNotFound } err = notification_repo.New().FilterContent("id", id).Delete() @@ -479,7 +479,7 @@ func (c *Client) Repair(id string) error { } if d == nil { - return sErrors.DeploymentNotFoundErr + return sErrors.ErrDeploymentNotFound } if !d.Ready() { @@ -499,7 +499,7 @@ func (c *Client) Repair(id string) error { err = c.K8s().Repair(id) if err != nil { - if errors.Is(err, sErrors.IngressHostInUseErr) { + if errors.Is(err, sErrors.ErrIngressHostInUse) { // The user should fix this error, so we don't return an error here utils.PrettyPrintError(err) } else { @@ -532,7 +532,7 @@ func (c *Client) Restart(id string) error { } if d == nil { - return sErrors.DeploymentNotFoundErr + return sErrors.ErrDeploymentNotFound } c.AddLogs(id, model.Log{ @@ -659,7 +659,7 @@ func (c *Client) CheckQuota(id string, opts *opts.QuotaOptions) error { } if deployment == nil { - return sErrors.DeploymentNotFoundErr + return sErrors.ErrDeploymentNotFound } replicasBefore := deployment.GetMainApp().Replicas @@ -711,7 +711,7 @@ func (c *Client) StartActivity(id string, activity string) error { canAdd, reason := c.CanAddActivity(id, activity) if !canAdd { if reason == "Deployment not found" { - return sErrors.DeploymentNotFoundErr + return sErrors.ErrDeploymentNotFound } return sErrors.NewFailedToStartActivityError(reason) diff --git a/service/v2/deployments/harbor_service/client.go b/service/v2/deployments/harbor_service/client.go index 717d0c92..ac95662c 100644 --- a/service/v2/deployments/harbor_service/client.go +++ b/service/v2/deployments/harbor_service/client.go @@ -74,7 +74,7 @@ func (c *Client) Get(opts *opts.Opts) (*model.Deployment, *harbor.Client, genera } if deployment == nil { - return nil, nil, nil, sErrors.DeploymentNotFoundErr + return nil, nil, nil, sErrors.ErrDeploymentNotFound } } @@ -92,7 +92,7 @@ func (c *Client) Get(opts *opts.Opts) (*model.Deployment, *harbor.Client, genera } if harborClient == nil { - return nil, nil, nil, sErrors.DeploymentNotFoundErr + return nil, nil, nil, sErrors.ErrDeploymentNotFound } } @@ -113,7 +113,7 @@ func (c *Client) Get(opts *opts.Opts) (*model.Deployment, *harbor.Client, genera harborGenerator = c.Generator(deployment, userID, zone) if harborGenerator == nil { - return nil, nil, nil, sErrors.DeploymentNotFoundErr + return nil, nil, nil, sErrors.ErrDeploymentNotFound } } diff --git a/service/v2/deployments/k8s_service/client.go b/service/v2/deployments/k8s_service/client.go index 2ea6737a..3c06c955 100644 --- a/service/v2/deployments/k8s_service/client.go +++ b/service/v2/deployments/k8s_service/client.go @@ -84,14 +84,14 @@ func (c *Client) Get(opts *opts.Opts) (*model.Deployment, *k8s.Client, generator } if deployment == nil { - return nil, nil, nil, sErrors.DeploymentNotFoundErr + return nil, nil, nil, sErrors.ErrDeploymentNotFound } } if opts.Client { zone := getZone(opts, deployment) if zone == nil { - return nil, nil, nil, sErrors.ZoneNotFoundErr + return nil, nil, nil, sErrors.ErrZoneNotFound } k8sClient, err = c.Client(zone) @@ -100,19 +100,19 @@ func (c *Client) Get(opts *opts.Opts) (*model.Deployment, *k8s.Client, generator } if k8sClient == nil { - return nil, nil, nil, sErrors.DeploymentNotFoundErr + return nil, nil, nil, sErrors.ErrDeploymentNotFound } } if opts.Generator { zone := getZone(opts, deployment) if zone == nil { - return nil, nil, nil, sErrors.ZoneNotFoundErr + return nil, nil, nil, sErrors.ErrZoneNotFound } k8sGenerator = c.Generator(deployment, k8sClient, zone) if k8sGenerator == nil { - return nil, nil, nil, sErrors.DeploymentNotFoundErr + return nil, nil, nil, sErrors.ErrDeploymentNotFound } } diff --git a/service/v2/deployments/k8s_service/k8s_service.go b/service/v2/deployments/k8s_service/k8s_service.go index f53b0459..c2ea088e 100644 --- a/service/v2/deployments/k8s_service/k8s_service.go +++ b/service/v2/deployments/k8s_service/k8s_service.go @@ -4,6 +4,9 @@ import ( "context" "errors" "fmt" + "slices" + "time" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" @@ -16,8 +19,6 @@ import ( "github.com/kthcloud/go-deploy/service/resources" "github.com/kthcloud/go-deploy/service/v2/deployments/opts" "github.com/kthcloud/go-deploy/utils" - "slices" - "time" ) // Create sets up K8s for the deployment. @@ -124,8 +125,8 @@ func (c *Client) Create(id string, params *model.DeploymentCreateParams) error { Exec() if err != nil { - if errors.Is(err, kErrors.IngressHostInUseErr) { - return makeError(sErrors.IngressHostInUseErr) + if errors.Is(err, kErrors.ErrIngressHostInUse) { + return makeError(sErrors.ErrIngressHostInUse) } return makeError(err) @@ -499,8 +500,8 @@ func (c *Client) Repair(id string) error { ).WithResourceID(public.Name).WithDbFunc(dbFunc(id, "ingressMap."+public.Name)).WithGenPublic(&public).Exec() if err != nil { - if errors.Is(err, kErrors.IngressHostInUseErr) { - return makeError(sErrors.IngressHostInUseErr) + if errors.Is(err, kErrors.ErrIngressHostInUse) { + return makeError(sErrors.ErrIngressHostInUse) } return makeError(err) @@ -567,7 +568,7 @@ func (c *Client) Repair(id string) error { anyMismatch := false pvcs := g.PVCs() - for mapName, _ := range d.Subsystems.K8s.PvcMap { + for mapName := range d.Subsystems.K8s.PvcMap { idx := slices.IndexFunc(pvcs, func(s k8sModels.PvcPublic) bool { return s.Name == mapName }) if idx == -1 { anyMismatch = true @@ -588,7 +589,7 @@ func (c *Client) Repair(id string) error { } pvs := g.PVs() - for mapName, _ := range d.Subsystems.K8s.PvMap { + for mapName := range d.Subsystems.K8s.PvMap { idx := slices.IndexFunc(pvs, func(s k8sModels.PvPublic) bool { return s.Name == mapName }) if idx == -1 { anyMismatch = true @@ -667,8 +668,8 @@ func (c *Client) SetupPodLogStream(ctx context.Context, zone *configModels.Zone, err = kc.SetupPodLogStream(ctx, podName, from, handler) if err != nil { - if errors.Is(err, kErrors.NotFoundErr) { - return sErrors.DeploymentNotFoundErr + if errors.Is(err, kErrors.ErrNotFound) { + return sErrors.ErrDeploymentNotFound } return err @@ -798,7 +799,7 @@ func (c *Client) recreatePvPvcDeployments(id string) error { d, err = c.Refresh(id) if err != nil { - if errors.Is(err, sErrors.DeploymentNotFoundErr) { + if errors.Is(err, sErrors.ErrDeploymentNotFound) { return nil } diff --git a/service/v2/deployments/logs_service.go b/service/v2/deployments/logs_service.go index 1d0a2d66..30233b0e 100644 --- a/service/v2/deployments/logs_service.go +++ b/service/v2/deployments/logs_service.go @@ -3,12 +3,13 @@ package deployments import ( "context" "fmt" + "time" + "github.com/kthcloud/go-deploy/pkg/db/resources/deployment_repo" "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/v2/deployments/opts" "github.com/kthcloud/go-deploy/utils" - "time" ) const ( @@ -35,7 +36,7 @@ func (c *Client) SetupLogStream(id string, ctx context.Context, handler func(str } if deployment == nil { - return errors.DeploymentNotFoundErr + return errors.ErrDeploymentNotFound } if deployment.BeingDeleted() { @@ -65,13 +66,13 @@ func (c *Client) SetupLogStream(id string, ctx context.Context, handler func(str } // Keep-alive packet every 30 seconds - ticker := time.Tick(30 * time.Second) + ticker := time.NewTicker(30 * time.Second) for { select { case <-ctx.Done(): return - case <-ticker: + case <-ticker.C: handler(MessageSourceKeepAlive, "[keep-alive]", "keep-alive", time.Now()) default: time.Sleep(FetchPeriod) diff --git a/service/v2/deployments/resources/k8s_generator.go b/service/v2/deployments/resources/k8s_generator.go index e2c9a00a..6505d61d 100644 --- a/service/v2/deployments/resources/k8s_generator.go +++ b/service/v2/deployments/resources/k8s_generator.go @@ -4,6 +4,13 @@ import ( "encoding/base64" "encoding/json" "fmt" + "math" + "path" + "regexp" + "slices" + "strings" + "time" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -17,12 +24,6 @@ import ( "github.com/kthcloud/go-deploy/service/generators" "github.com/kthcloud/go-deploy/utils" v1 "k8s.io/api/core/v1" - "math" - "path" - "regexp" - "slices" - "strings" - "time" ) type K8sGenerator struct { @@ -338,7 +339,7 @@ func (kg *K8sGenerator) Ingresses() []models.IngressPublic { if mainApp.CustomDomain != nil && mainApp.CustomDomain.Status == model.CustomDomainStatusActive { customIn := models.IngressPublic{ - Name: fmt.Sprintf(constants.WithCustomDomainSuffix(kg.deployment.Name)), + Name: fmt.Sprint(constants.WithCustomDomainSuffix(kg.deployment.Name)), Namespace: kg.namespace, ServiceName: serviceName, ServicePort: servicePort, diff --git a/service/v2/jobs/job_service.go b/service/v2/jobs/job_service.go index 6da3bbd5..08b52b36 100644 --- a/service/v2/jobs/job_service.go +++ b/service/v2/jobs/job_service.go @@ -83,7 +83,7 @@ func (c *Client) Create(id, userID, jobType, version string, args map[string]int // Update updates a job. func (c *Client) Update(id string, jobUpdateDTO *body.JobUpdate) (*model.Job, error) { if c.V2.Auth() != nil && !c.V2.Auth().User.IsAdmin { - return nil, sErrors.ForbiddenErr + return nil, sErrors.ErrForbidden } var params model.JobUpdateParams diff --git a/service/v2/notifications/notification_service.go b/service/v2/notifications/notification_service.go index cdc072d3..5e4e5cbe 100644 --- a/service/v2/notifications/notification_service.go +++ b/service/v2/notifications/notification_service.go @@ -108,7 +108,7 @@ func (c *Client) Delete(id string) error { } if !exists { - return sErrors.NotificationNotFoundErr + return sErrors.ErrNotificationNotFound } return client.DeleteByID(id) diff --git a/service/v2/resource_migrations/resource_migration_service.go b/service/v2/resource_migrations/resource_migration_service.go index ab2e46ba..366e83bb 100644 --- a/service/v2/resource_migrations/resource_migration_service.go +++ b/service/v2/resource_migrations/resource_migration_service.go @@ -82,7 +82,7 @@ func (c *Client) Create(id, userID string, migrationCreate *body.ResourceMigrati } if resourceType == nil { - return nil, nil, sErrors.ResourceNotFoundErr + return nil, nil, sErrors.ErrResourceNotFound } canAccess, err := c.canAccessResource(migrationCreate.ResourceID, *resourceType) @@ -91,13 +91,13 @@ func (c *Client) Create(id, userID string, migrationCreate *body.ResourceMigrati } if !canAccess { - return nil, nil, sErrors.ResourceNotFoundErr + return nil, nil, sErrors.ErrResourceNotFound } switch migrationCreate.Type { case model.ResourceMigrationTypeUpdateOwner: if migrationCreate.UpdateOwner == nil { - return nil, nil, sErrors.BadResourceMigrationParamsErr + return nil, nil, sErrors.ErrBadResourceMigrationParams } ownerID, err := c.getOwnerID(migrationCreate.ResourceID, *resourceType) @@ -106,11 +106,11 @@ func (c *Client) Create(id, userID string, migrationCreate *body.ResourceMigrati } if ownerID == nil { - return nil, nil, sErrors.ResourceNotFoundErr + return nil, nil, sErrors.ErrResourceNotFound } if *ownerID == migrationCreate.UpdateOwner.OwnerID { - return nil, nil, sErrors.AlreadyMigratedErr + return nil, nil, sErrors.ErrAlreadyMigrated } var status string @@ -125,7 +125,7 @@ func (c *Client) Create(id, userID string, migrationCreate *body.ResourceMigrati OldOwnerID: *ownerID, }) default: - return nil, nil, sErrors.BadResourceMigrationTypeErr + return nil, nil, sErrors.ErrBadResourceMigrationType } } @@ -145,7 +145,7 @@ func (c *Client) CreateMigrationUpdateOwner(id, userID, resourceID, resourceType resourceMigration, err := rmc.Create(id, userID, resourceID, model.ResourceMigrationTypeUpdateOwner, resourceType, &code, status, params) if err != nil { if errors.Is(err, db.ErrUniqueConstraint) { - return nil, nil, sErrors.ResourceMigrationAlreadyExistsErr + return nil, nil, sErrors.ErrResourceMigrationAlreadyExists } return nil, nil, makeError(err) @@ -212,7 +212,7 @@ func (c *Client) CreateMigrationUpdateOwner(id, userID, resourceID, resourceType return resourceMigration, &jobID, nil default: - return nil, nil, sErrors.BadResourceMigrationStatusErr + return nil, nil, sErrors.ErrBadResourceMigrationStatus } } @@ -236,12 +236,12 @@ func (c *Client) Update(id string, migrationUpdate *body.ResourceMigrationUpdate } if resourceMigration == nil { - return nil, nil, sErrors.ResourceMigrationNotFoundErr + return nil, nil, sErrors.ErrResourceMigrationNotFound } if migrationUpdate.Status == model.ResourceMigrationStatusAccepted { if resourceMigration.Status == model.ResourceMigrationStatusAccepted { - return nil, nil, sErrors.AlreadyAcceptedErr + return nil, nil, sErrors.ErrAlreadyAccepted } canDoUpdate := false @@ -249,7 +249,7 @@ func (c *Client) Update(id string, migrationUpdate *body.ResourceMigrationUpdate requireCodeCheck := c.V2.HasAuth() && !c.V2.Auth().User.IsAdmin if requireCodeCheck { if migrationUpdate.Code == nil { - return nil, nil, sErrors.BadMigrationCodeErr + return nil, nil, sErrors.ErrBadMigrationCode } if resourceMigration.Code == nil || *migrationUpdate.Code == *resourceMigration.Code { @@ -260,7 +260,7 @@ func (c *Client) Update(id string, migrationUpdate *body.ResourceMigrationUpdate } if !canDoUpdate { - return nil, nil, sErrors.BadMigrationCodeErr + return nil, nil, sErrors.ErrBadMigrationCode } updateParams := model.ResourceMigrationUpdateParams{}.FromDTO(migrationUpdate) @@ -284,12 +284,12 @@ func (c *Client) Update(id string, migrationUpdate *body.ResourceMigrationUpdate } if resourceMigration == nil { - return nil, nil, sErrors.ResourceMigrationNotFoundErr + return nil, nil, sErrors.ErrResourceMigrationNotFound } return resourceMigration, jobID, nil } else { - return nil, nil, sErrors.BadResourceMigrationStatusErr + return nil, nil, sErrors.ErrBadResourceMigrationStatus } } @@ -394,7 +394,7 @@ func (c *Client) getResourceName(id string, resourceType string) (*string, error case model.ResourceTypeDeployment: return deployment_repo.New().GetName(id) default: - return nil, sErrors.BadResourceMigrationResourceTypeErr + return nil, sErrors.ErrBadResourceMigrationResourceType } } @@ -431,7 +431,7 @@ func (c *Client) getOwnerID(id string, resourceType string) (*string, error) { } if vm == nil { - return nil, sErrors.ResourceNotFoundErr + return nil, sErrors.ErrResourceNotFound } return &vm.OwnerID, nil @@ -442,11 +442,11 @@ func (c *Client) getOwnerID(id string, resourceType string) (*string, error) { } if deployment == nil { - return nil, sErrors.ResourceNotFoundErr + return nil, sErrors.ErrResourceNotFound } return &deployment.OwnerID, nil } - return nil, sErrors.BadResourceMigrationResourceTypeErr + return nil, sErrors.ErrBadResourceMigrationResourceType } diff --git a/service/v2/sms/k8s_service/client.go b/service/v2/sms/k8s_service/client.go index 1839e758..a6818b8d 100644 --- a/service/v2/sms/k8s_service/client.go +++ b/service/v2/sms/k8s_service/client.go @@ -82,7 +82,7 @@ func (c *Client) Get(opts *opts.Opts) (*model.SM, *k8s.Client, generators.K8sGen } if sm == nil { - return nil, nil, nil, sErrors.SmNotFoundErr + return nil, nil, nil, sErrors.ErrSmNotFound } } @@ -102,7 +102,7 @@ func (c *Client) Get(opts *opts.Opts) (*model.SM, *k8s.Client, generators.K8sGen } if zone == nil { - return nil, nil, nil, sErrors.ZoneNotFoundErr + return nil, nil, nil, sErrors.ErrZoneNotFound } k8sClient, err = c.Client(userID, zone) @@ -111,7 +111,7 @@ func (c *Client) Get(opts *opts.Opts) (*model.SM, *k8s.Client, generators.K8sGen } if k8sClient == nil { - return nil, nil, nil, sErrors.SmNotFoundErr + return nil, nil, nil, sErrors.ErrSmNotFound } } @@ -125,7 +125,7 @@ func (c *Client) Get(opts *opts.Opts) (*model.SM, *k8s.Client, generators.K8sGen k8sGenerator = c.Generator(sm, k8sClient, zone) if k8sGenerator == nil { - return nil, nil, nil, sErrors.SmNotFoundErr + return nil, nil, nil, sErrors.ErrSmNotFound } } diff --git a/service/v2/sms/k8s_service/k8s_service.go b/service/v2/sms/k8s_service/k8s_service.go index 2143ee5d..681ff4ec 100644 --- a/service/v2/sms/k8s_service/k8s_service.go +++ b/service/v2/sms/k8s_service/k8s_service.go @@ -3,6 +3,7 @@ package k8s_service import ( "errors" "fmt" + "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/sm_repo" "github.com/kthcloud/go-deploy/pkg/log" @@ -114,8 +115,8 @@ func (c *Client) Create(id string, params *model.SmCreateParams) error { Exec() if err != nil { - if errors.Is(err, kErrors.IngressHostInUseErr) { - return makeError(sErrors.IngressHostInUseErr) + if errors.Is(err, kErrors.ErrIngressHostInUse) { + return makeError(sErrors.ErrIngressHostInUse) } return makeError(err) @@ -312,8 +313,8 @@ func (c *Client) Repair(id string) error { ).WithResourceID(public.Name).WithDbFunc(dbFunc(id, "ingressMap."+public.Name)).WithGenPublic(&public).Exec() if err != nil { - if errors.Is(err, kErrors.IngressHostInUseErr) { - return makeError(sErrors.IngressHostInUseErr) + if errors.Is(err, kErrors.ErrIngressHostInUse) { + return makeError(sErrors.ErrIngressHostInUse) } return makeError(err) @@ -353,7 +354,7 @@ func (c *Client) Repair(id string) error { anyMismatch := false pvcs := g.PVCs() - for mapName, _ := range sm.Subsystems.K8s.PvcMap { + for mapName := range sm.Subsystems.K8s.PvcMap { idx := slices.IndexFunc(pvcs, func(s k8sModels.PvcPublic) bool { return s.Name == mapName }) if idx == -1 { anyMismatch = true @@ -374,7 +375,7 @@ func (c *Client) Repair(id string) error { } pvs := g.PVs() - for mapName, _ := range sm.Subsystems.K8s.PvMap { + for mapName := range sm.Subsystems.K8s.PvMap { idx := slices.IndexFunc(pvs, func(s k8sModels.PvPublic) bool { return s.Name == mapName }) if idx == -1 { anyMismatch = true @@ -449,7 +450,7 @@ func (c *Client) recreatePvPvcDeployments(id string) error { sm, err = c.Refresh(id) if err != nil { - if errors.Is(err, sErrors.SmNotFoundErr) { + if errors.Is(err, sErrors.ErrSmNotFound) { return nil } diff --git a/service/v2/sms/sm_service.go b/service/v2/sms/sm_service.go index cbfdfe7c..eb02e03c 100644 --- a/service/v2/sms/sm_service.go +++ b/service/v2/sms/sm_service.go @@ -81,7 +81,7 @@ func (c *Client) Create(id, userID string, params *model.SmCreateParams) error { _, err := sm_repo.New().Create(id, userID, params) if err != nil { if errors.Is(err, sm_repo.ErrAlreadyExists) { - return sErrors.SmAlreadyExistsErr + return sErrors.ErrSmAlreadyExists } return makeErr(err) diff --git a/service/v2/system/registration_service.go b/service/v2/system/registration_service.go index e44d2754..4f6bf600 100644 --- a/service/v2/system/registration_service.go +++ b/service/v2/system/registration_service.go @@ -11,7 +11,7 @@ import ( func (c *Client) RegisterNode(params *body.HostRegisterParams) error { // Validate token if params.Token != config.Config.Discovery.Token { - return sErrors.BadDiscoveryTokenErr + return sErrors.ErrBadDiscoveryToken } if params.DisplayName == "" { @@ -24,7 +24,7 @@ func (c *Client) RegisterNode(params *body.HostRegisterParams) error { // Check if node is schedulable zone := config.Config.GetZone(params.Zone) if zone == nil { - return sErrors.ZoneNotFoundErr + return sErrors.ErrZoneNotFound } k8sClient, err := c.V2.Deployments().K8s().Client(zone) @@ -38,7 +38,7 @@ func (c *Client) RegisterNode(params *body.HostRegisterParams) error { } if k8sNode == nil { - return sErrors.HostNotFoundErr + return sErrors.ErrHostNotFound } params.Schedulable = k8sNode.Schedulable diff --git a/service/v2/teams/team_service.go b/service/v2/teams/team_service.go index faca54ca..a81f50ed 100644 --- a/service/v2/teams/team_service.go +++ b/service/v2/teams/team_service.go @@ -134,7 +134,7 @@ func (c *Client) Create(id, ownerID string, dtoCreateTeam *body.TeamCreate) (*mo team, err := team_repo.New().Create(id, ownerID, params) if err != nil { if errors.Is(err, team_repo.ErrNameTaken) { - return nil, sErrors.TeamNameTakenErr + return nil, sErrors.ErrTeamNameTaken } return nil, err @@ -231,7 +231,7 @@ func (c *Client) Delete(id string) error { } if !exists { - return sErrors.TeamNotFoundErr + return sErrors.ErrTeamNotFound } err = notification_repo.New().FilterContent("id", id).Delete() @@ -290,11 +290,11 @@ func (c *Client) Join(id string, dtoTeamJoin *body.TeamJoin) (*model.Team, error } if team.GetMemberMap()[c.V2.Auth().User.ID].MemberStatus != model.TeamMemberStatusInvited { - return team, sErrors.NotInvitedErr + return team, sErrors.ErrNotInvited } if team.GetMemberMap()[c.V2.Auth().User.ID].InvitationCode != params.InvitationCode { - return nil, sErrors.BadInviteCodeErr + return nil, sErrors.ErrBadInviteCode } updatedMember := team.GetMemberMap()[c.V2.Auth().User.ID] diff --git a/service/v2/users/api_key/api_key.go b/service/v2/users/api_key/api_key.go index e8e74f40..d7a3ec3c 100644 --- a/service/v2/users/api_key/api_key.go +++ b/service/v2/users/api_key/api_key.go @@ -1,12 +1,13 @@ package api_key import ( + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/user_repo" sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/utils" - "time" ) // Create generates a new API key for the user. @@ -19,7 +20,7 @@ func (c *Client) Create(userID string, dtoApiKeyCreate *body.ApiKeyCreate) (*mod } if user == nil { - return nil, sErrors.UserNotFoundErr + return nil, sErrors.ErrUserNotFound } params := model.ApiKeyCreateParams{}.FromDTO(dtoApiKeyCreate, key) @@ -34,7 +35,7 @@ func (c *Client) Create(userID string, dtoApiKeyCreate *body.ApiKeyCreate) (*mod // Check duplicate name for the API key for _, k := range user.ApiKeys { if k.Name == apiKey.Name { - return nil, sErrors.ApiKeyNameTakenErr + return nil, sErrors.ErrApiKeyNameTaken } } @@ -55,7 +56,7 @@ func (c *Client) List(userID string) ([]model.ApiKey, error) { } if user == nil { - return nil, sErrors.UserNotFoundErr + return nil, sErrors.ErrUserNotFound } return user.ApiKeys, nil @@ -69,7 +70,7 @@ func (c *Client) Delete(userID string, name string) error { } if user == nil { - return sErrors.UserNotFoundErr + return sErrors.ErrUserNotFound } apiKeys := make([]model.ApiKey, 0) diff --git a/service/v2/users/user_service.go b/service/v2/users/user_service.go index c2706c59..bf3d25ab 100644 --- a/service/v2/users/user_service.go +++ b/service/v2/users/user_service.go @@ -3,6 +3,10 @@ package users import ( "crypto/sha256" "encoding/hex" + "net/http" + "strings" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -10,9 +14,6 @@ import ( sErrors "github.com/kthcloud/go-deploy/service/errors" "github.com/kthcloud/go-deploy/service/utils" "github.com/kthcloud/go-deploy/service/v2/users/opts" - "net/http" - "strings" - "time" ) // Get gets a user @@ -212,7 +213,7 @@ func (c *Client) Update(userID string, dtoUserUpdate *body.UserUpdate) (*model.U } if user == nil { - return nil, sErrors.UserNotFoundErr + return nil, sErrors.ErrUserNotFound } userUpdate := model.UserUpdateParams{}.FromDTO(dtoUserUpdate, user.ApiKeys) diff --git a/service/v2/vms/gpu_leases/gpu_lease_service.go b/service/v2/vms/gpu_leases/gpu_lease_service.go index 482960a1..5f8de137 100644 --- a/service/v2/vms/gpu_leases/gpu_lease_service.go +++ b/service/v2/vms/gpu_leases/gpu_lease_service.go @@ -3,13 +3,14 @@ package gpu_leases import ( "errors" "fmt" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/db/resources/gpu_lease_repo" sErrors "github.com/kthcloud/go-deploy/service/errors" sUtils "github.com/kthcloud/go-deploy/service/utils" "github.com/kthcloud/go-deploy/service/v2/vms/opts" - "time" ) // Get gets a GPU lease by ID @@ -76,7 +77,7 @@ func (c *Client) GetByVmID(vmID string, opts ...opts.GetGpuLeaseOpts) (*model.Gp } if vm == nil { - return nil, makeError(sErrors.VmNotFoundErr) + return nil, makeError(sErrors.ErrVmNotFound) } glc := gpu_lease_repo.New() @@ -122,7 +123,7 @@ func (c *Client) List(opts ...opts.ListGpuLeaseOpts) ([]model.GpuLease, error) { } if vm == nil { - return nil, makeError(sErrors.VmNotFoundErr) + return nil, makeError(sErrors.ErrVmNotFound) } if vm.OwnerID != c.V2.Auth().User.ID { @@ -196,8 +197,8 @@ func (c *Client) Create(leaseID, userID string, dtoGpuLeaseCreate *body.GpuLease err := gpu_lease_repo.New().Create(leaseID, userID, params.GpuGroupName, leaseDuration) if err != nil { - if errors.Is(err, gpu_lease_repo.GpuLeaseAlreadyExistsErr) { - return makeError(sErrors.GpuLeaseAlreadyExistsErr) + if errors.Is(err, gpu_lease_repo.ErrGpuLeaseAlreadyExists) { + return makeError(sErrors.ErrGpuLeaseAlreadyExists) } return makeError(err) @@ -218,7 +219,7 @@ func (c *Client) Update(id string, dtoGpuLeaseUpdate *body.GpuLeaseUpdate) error } if lease == nil { - return makeError(sErrors.GpuLeaseNotFoundErr) + return makeError(sErrors.ErrGpuLeaseNotFound) } params := model.GpuLeaseUpdateParams{}.FromDTO(dtoGpuLeaseUpdate) @@ -231,7 +232,7 @@ func (c *Client) Update(id string, dtoGpuLeaseUpdate *body.GpuLeaseUpdate) error // If the lease was request to be activated, check if that is allowed but checking if the lease is assigned if params.ActivatedAt != nil && lease.AssignedAt == nil { - return makeError(sErrors.GpuLeaseNotAssignedErr) + return makeError(sErrors.ErrGpuLeaseNotAssigned) } // If the lease is trying to update to the same VM, ignore the attaching @@ -242,8 +243,8 @@ func (c *Client) Update(id string, dtoGpuLeaseUpdate *body.GpuLeaseUpdate) error err = gpu_lease_repo.New().UpdateWithParams(id, params) if err != nil { - if errors.Is(err, gpu_lease_repo.VmAlreadyAttachedErr) { - return makeError(sErrors.VmAlreadyAttachedErr) + if errors.Is(err, gpu_lease_repo.ErrVmAlreadyAttached) { + return makeError(sErrors.ErrVmAlreadyAttached) } return makeError(err) @@ -252,7 +253,7 @@ func (c *Client) Update(id string, dtoGpuLeaseUpdate *body.GpuLeaseUpdate) error // If the lease already has a VM attached, detach it if lease.VmID != nil { err = c.V2.VMs().K8s().DetachGPU(*lease.VmID) - if err != nil && !errors.Is(err, sErrors.VmNotFoundErr) { + if err != nil && !errors.Is(err, sErrors.ErrVmNotFound) { return makeError(err) } } @@ -291,7 +292,7 @@ func (c *Client) Delete(id string) error { // Detach the GPU if lease.VmID != nil { err = c.V2.VMs().K8s().DetachGPU(*lease.VmID) - if err != nil && !errors.Is(err, sErrors.VmNotFoundErr) { + if err != nil && !errors.Is(err, sErrors.ErrVmNotFound) { return makeError(err) } } @@ -352,13 +353,16 @@ func (c *Client) GetQueuePosition(id string) (int, error) { } if lease == nil { - return 0, makeError(sErrors.GpuLeaseNotFoundErr) + return 0, makeError(sErrors.ErrGpuLeaseNotFound) } count, err := c.Count(opts.ListGpuLeaseOpts{ GpuGroupID: &lease.GpuGroupID, CreatedBefore: &lease.CreatedAt, }) + if err != nil { + return 0, makeError(err) + } gpuGroup, err := c.V2.VMs().GpuGroups().Get(lease.GpuGroupID) if err != nil { @@ -366,7 +370,7 @@ func (c *Client) GetQueuePosition(id string) (int, error) { } if gpuGroup == nil { - return 0, makeError(sErrors.GpuGroupNotFoundErr) + return 0, makeError(sErrors.ErrGpuGroupNotFound) } // Add 1 to the queue position to make it human-readable (queue position 1 means next in line) diff --git a/service/v2/vms/k8s_service/client.go b/service/v2/vms/k8s_service/client.go index ecf61141..6d02a506 100644 --- a/service/v2/vms/k8s_service/client.go +++ b/service/v2/vms/k8s_service/client.go @@ -2,6 +2,7 @@ package k8s_service import ( "fmt" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -95,14 +96,14 @@ func (c *Client) Get(opts *opts.Opts) (*model.VM, *k8s.Client, generators.K8sGen } if vm == nil { - return nil, nil, nil, sErrors.VmNotFoundErr + return nil, nil, nil, sErrors.ErrVmNotFound } } if opts.Client { zone := getZone(opts, vm) if zone == nil { - return nil, nil, nil, sErrors.ZoneNotFoundErr + return nil, nil, nil, sErrors.ErrZoneNotFound } kc, err = c.Client(zone) @@ -111,19 +112,19 @@ func (c *Client) Get(opts *opts.Opts) (*model.VM, *k8s.Client, generators.K8sGen } if kc == nil { - return nil, nil, nil, sErrors.VmNotFoundErr + return nil, nil, nil, sErrors.ErrVmNotFound } } if opts.Generator { zone := getZone(opts, vm) if zone == nil { - return nil, nil, nil, sErrors.ZoneNotFoundErr + return nil, nil, nil, sErrors.ErrZoneNotFound } g = c.Generator(vm, kc, zone, opts.ExtraOpts.ExtraSshKeys) if g == nil { - return nil, nil, nil, sErrors.VmNotFoundErr + return nil, nil, nil, sErrors.ErrVmNotFound } } diff --git a/service/v2/vms/k8s_service/k8s_service.go b/service/v2/vms/k8s_service/k8s_service.go index f6796001..3b75502b 100644 --- a/service/v2/vms/k8s_service/k8s_service.go +++ b/service/v2/vms/k8s_service/k8s_service.go @@ -32,7 +32,7 @@ func (c *Client) Create(id string, params *model.VmCreateParams) error { vm, kc, g, err := c.Get(OptsAll(id, opts.ExtraOpts{ExtraSshKeys: []string{config.Config.VM.AdminSshPublicKey}})) if err != nil { - if errors.Is(err, sErrors.VmNotFoundErr) { + if errors.Is(err, sErrors.ErrVmNotFound) { log.Println("VM not found when setting up k8s for", params.Name, ". Assuming it was deleted") return nil } @@ -105,7 +105,7 @@ func (c *Client) Create(id string, params *model.VmCreateParams) error { vmPort, err := vm_port_repo.New().GetOrLeaseAny(port.TargetPort, vm.ID, vm.Zone) if err != nil { if errors.Is(err, vm_port_repo.ErrNoPortsAvailable) { - return makeError(sErrors.NoPortsAvailableErr) + return makeError(sErrors.ErrNoPortsAvailable) } return makeError(err) @@ -132,8 +132,8 @@ func (c *Client) Create(id string, params *model.VmCreateParams) error { Exec() if err != nil { - if errors.Is(err, kErrors.IngressHostInUseErr) { - return makeError(sErrors.IngressHostInUseErr) + if errors.Is(err, kErrors.ErrIngressHostInUse) { + return makeError(sErrors.ErrIngressHostInUse) } return makeError(err) @@ -170,7 +170,7 @@ func (c *Client) Delete(id string, overwriteUserID ...string) error { vm, kc, _, err := c.Get(OptsNoGenerator(id, opts.ExtraOpts{UserID: userID})) if err != nil { - if errors.Is(err, sErrors.VmNotFoundErr) { + if errors.Is(err, sErrors.ErrVmNotFound) { log.Println("VM not found when deleting k8s for", id, ". Assuming it was deleted") return nil } @@ -299,7 +299,7 @@ func (c *Client) Repair(id string) error { vm, kc, g, err := c.Get(OptsAll(id, opts.ExtraOpts{ExtraSshKeys: []string{config.Config.VM.AdminSshPublicKey}})) if err != nil { - if errors.Is(err, sErrors.VmNotFoundErr) { + if errors.Is(err, sErrors.ErrVmNotFound) { log.Println("VM not found when deleting k8s for", id, ". Assuming it was deleted") return nil } @@ -390,7 +390,7 @@ func (c *Client) Repair(id string) error { vmPort, err := vm_port_repo.New().GetOrLeaseAny(port.TargetPort, vm.ID, vm.Zone) if err != nil { if errors.Is(err, vm_port_repo.ErrNoPortsAvailable) { - return makeError(sErrors.NoPortsAvailableErr) + return makeError(sErrors.ErrNoPortsAvailable) } return makeError(err) @@ -435,8 +435,8 @@ func (c *Client) Repair(id string) error { ).WithResourceID(public.Name).WithDbFunc(dbFunc(id, "ingressMap."+public.Name)).WithGenPublic(&public).Exec() if err != nil { - if errors.Is(err, kErrors.IngressHostInUseErr) { - return makeError(sErrors.IngressHostInUseErr) + if errors.Is(err, kErrors.ErrIngressHostInUse) { + return makeError(sErrors.ErrIngressHostInUse) } return makeError(err) @@ -482,7 +482,9 @@ func (c *Client) AttachGPU(vmID, groupName string) error { vm, kc, _, err := c.Get(OptsAll(vmID)) if vm == nil { - return makeError(sErrors.VmNotFoundErr) + return makeError(sErrors.ErrVmNotFound) + } else if err != nil { + return makeError(err) } // Set the GPU to the VM @@ -513,7 +515,9 @@ func (c *Client) DetachGPU(vmID string) error { vm, kc, _, err := c.Get(OptsAll(vmID)) if vm == nil { - return makeError(sErrors.VmNotFoundErr) + return makeError(sErrors.ErrVmNotFound) + } else if err != nil { + return makeError(err) } // Remove the GPU from the VM @@ -544,7 +548,7 @@ func (c *Client) DoAction(id string, action *model.VmActionParams) error { vm, kc, _, err := c.Get(OptsAll(id)) if err != nil { - if errors.Is(err, sErrors.VmNotFoundErr) { + if errors.Is(err, sErrors.ErrVmNotFound) { log.Println("VM not found when performing action", action.Action, "on", id, ". Assuming it was deleted") return nil } @@ -643,7 +647,7 @@ func (c *Client) Synchronize(zoneName string, gpuGroups []model.GpuGroup) error // Ensure zone has KubeVirt capabilities zone := config.Config.GetZone(zoneName) if zone == nil { - return makeError(sErrors.ZoneNotFoundErr) + return makeError(sErrors.ErrZoneNotFound) } if !zone.HasCapability(configModels.ZoneCapabilityVM) { diff --git a/service/v2/vms/vm_service.go b/service/v2/vms/vm_service.go index 46b63f77..2084a02c 100644 --- a/service/v2/vms/vm_service.go +++ b/service/v2/vms/vm_service.go @@ -213,8 +213,8 @@ func (c *Client) Create(id, ownerID string, dtoVmCreate *body.VmCreate) error { _, err := vm_repo.New(version.V2).Create(id, ownerID, ¶ms) if err != nil { - if errors.Is(err, rErrors.NonUniqueFieldErr) { - return sErrors.NonUniqueFieldErr + if errors.Is(err, rErrors.ErrNonUniqueField) { + return sErrors.ErrNonUniqueField } return makeError(err) @@ -261,8 +261,8 @@ func (c *Client) Update(id string, dtoVmUpdate *body.VmUpdate) error { err := vm_repo.New(version.V2).UpdateWithParams(id, &vmUpdate) if err != nil { - if errors.Is(err, rErrors.NonUniqueFieldErr) { - return sErrors.NonUniqueFieldErr + if errors.Is(err, rErrors.ErrNonUniqueField) { + return sErrors.ErrNonUniqueField } return makeError(err) @@ -301,7 +301,7 @@ func (c *Client) Delete(id string) error { } if vm == nil { - return sErrors.VmNotFoundErr + return sErrors.ErrVmNotFound } err = notification_repo.New().FilterContent("id", id).Delete() @@ -353,7 +353,7 @@ func (c *Client) IsAccessible(id string) (bool, error) { } if !exists { - return false, makeError(sErrors.VmNotFoundErr) + return false, makeError(sErrors.ErrVmNotFound) } if c.V2.HasAuth() { @@ -459,7 +459,7 @@ func (c *Client) UpdateOwner(id string, params *model.VmUpdateOwnerParams) error } if vm == nil { - return sErrors.VmNotFoundErr + return sErrors.ErrVmNotFound } err = vm_repo.New(version.V2).UpdateWithParams(id, &model.VmUpdateParams{ @@ -570,7 +570,7 @@ func (c *Client) SshConnectionString(id string) (*string, error) { zone := config.Config.GetZone(vm.Zone) if zone == nil { - return nil, makeError(sErrors.ZoneNotFoundErr) + return nil, makeError(sErrors.ErrZoneNotFound) } var sshConnectionString *string @@ -638,7 +638,7 @@ func (c *Client) CheckQuota(id, userID string, quota *model.Quotas, opts ...opts } if vm == nil { - return makeError(sErrors.VmNotFoundErr) + return makeError(sErrors.ErrVmNotFound) } if o.Update.CpuCores != nil { diff --git a/test/acc/subsystems/k8s/helpers.go b/test/acc/subsystems/k8s/helpers.go index 82a87316..c357574d 100644 --- a/test/acc/subsystems/k8s/helpers.go +++ b/test/acc/subsystems/k8s/helpers.go @@ -1,6 +1,8 @@ package k8s import ( + "testing" + "github.com/kthcloud/go-deploy/pkg/config" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s" "github.com/kthcloud/go-deploy/pkg/subsystems/k8s/models" @@ -8,7 +10,6 @@ import ( "github.com/kthcloud/go-deploy/test/acc" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" - "testing" ) func withContext(t *testing.T, zoneName ...string) (*k8s.Client, *models.NamespacePublic) { @@ -33,7 +34,7 @@ func withClient(t *testing.T, namespace string, zoneName ...string) *k8s.Client Namespace: namespace, }) if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } return client diff --git a/test/e2e/common.go b/test/e2e/common.go index 4892ee6d..c7f9943f 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -4,16 +4,17 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/google/uuid" - "github.com/kthcloud/go-deploy/dto/v2/body" - "github.com/kthcloud/go-deploy/models/model" - "github.com/kthcloud/go-deploy/pkg/sys" - "github.com/stretchr/testify/assert" "io" "net/http" "strings" "testing" "time" + + "github.com/google/uuid" + "github.com/kthcloud/go-deploy/dto/v2/body" + "github.com/kthcloud/go-deploy/models/model" + "github.com/kthcloud/go-deploy/pkg/sys" + "github.com/stretchr/testify/assert" ) const ( @@ -196,6 +197,7 @@ func parseRawBody(body []byte, parsedBody interface{}) error { func MustParse[okType any](t *testing.T, resp *http.Response) okType { if resp == nil { assert.FailNow(t, "response is nil. is the server running?") + return *new(okType) } if resp.StatusCode > 299 { diff --git a/test/e2e/v2/team_utils.go b/test/e2e/v2/team_utils.go index 6a4dbb60..3386388a 100644 --- a/test/e2e/v2/team_utils.go +++ b/test/e2e/v2/team_utils.go @@ -1,13 +1,14 @@ package v2 import ( + "net/http" + "testing" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/test" "github.com/kthcloud/go-deploy/test/e2e" "github.com/stretchr/testify/assert" - "net/http" - "testing" ) const ( @@ -43,9 +44,7 @@ func UpdateTeam(t *testing.T, id string, teamUpdate body.TeamUpdate, user ...str var requested []string var result []string - for _, resource := range *teamUpdate.Resources { - requested = append(requested, resource) - } + requested = append(requested, *teamUpdate.Resources...) for _, resource := range teamRead.Resources { result = append(result, resource.ID) diff --git a/utils/utils.go b/utils/utils.go index 2b0bfc34..c2a7463b 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,10 +5,11 @@ import ( "encoding/base64" "errors" "fmt" - "github.com/kthcloud/go-deploy/pkg/log" "math/rand" "strings" "time" + + "github.com/kthcloud/go-deploy/pkg/log" ) // HashString hashes a string using sha256 and returns the base64 encoded string @@ -123,11 +124,12 @@ const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 // GenerateSalt generates the salt that can be used when hashing a password func GenerateSalt() string { - //goland:noinspection GoDeprecation - rand.Seed(time.Now().UnixNano()) + src := rand.NewSource(time.Now().UnixNano()) + rng := rand.New(src) + salt := make([]byte, 16) for i := range salt { - salt[i] = alphabet[rand.Intn(len(alphabet))] + salt[i] = alphabet[rng.Intn(len(alphabet))] } return string(salt) } From 20b136e5af59344f1fdfd4b6d78606b91dde62bf Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 18:09:15 +0100 Subject: [PATCH 15/36] add test target to run acc and e2e tests --- Makefile | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9499336e..c4db69ce 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,21 @@ release: docs @echo "Build complete." test: clean build - @go test ./... + @go test ./test/acc/... + @echo "Starting go-deploy in test mode..." + @./$(BUILD_DIR)/$(BINARY_NAME)$(EXT) --mode=test & echo $$! > go_deploy.pid + @echo "Waiting for API to become ready..." + @until curl --output /dev/null --silent --head --fail http://localhost:8080/healthz; do \ + echo "Waiting for API to start"; \ + sleep 1; \ + done + @echo "API is ready!" + @echo "Running e2e tests..." + @go test ./test/e2e/... + @if [ -f go_deploy.pid ]; then \ + echo "Stopping go-deploy..."; \ + kill $$(cat go_deploy.pid) && rm -f go_deploy.pid; \ + fi acc: clean build @go test ./test/acc/... From bfe6ebf9e4104c67d91ba380d938ebe92f4869f9 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 18:34:56 +0100 Subject: [PATCH 16/36] Add target to lint the code --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c4db69ce..85f11e0c 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ BUILDTIMESTAMP=$(shell date -u +%Y%m%d%H%M%S) EXT=$(if $(filter windows,$(GOOS)),.exe,) # Targets -.PHONY: all clean build run clean docs release test acc e2e +.PHONY: all clean build run clean docs release test acc e2e lint all: build @@ -69,3 +69,6 @@ e2e: clean build echo "Stopping go-deploy..."; \ kill $$(cat go_deploy.pid) && rm -f go_deploy.pid; \ fi + +lint: + @./scripts/check-lint.sh From ccfdda0a13eb55fd44393cf4afd6737f9a2f47a5 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 19:06:57 +0100 Subject: [PATCH 17/36] dockerfile improvements --- .dockerignore | 7 +++++++ Dockerfile | 17 +++++++++------ cached.Dockerfile | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 .dockerignore create mode 100644 cached.Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..953b02da --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +.github +bin +config.local.yml +kube +README.md +LICENSE +Makefile diff --git a/Dockerfile b/Dockerfile index de866f83..36f9abd3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,23 @@ ############################ # STEP 1 build executable binary ############################ -FROM golang:alpine AS builder +FROM --platform=$BUILDPLATFORM golang:alpine AS builder # Install git. RUN apk update && apk add --no-cache git=~2 # Set up working directory WORKDIR /app -COPY . . +# Copy go.mod and go.sum separately so we only invalidate the downloading layers if we need to +COPY go.mod go.sum ./ # Fetch dependencies and build the binary ENV GO111MODULE=on -RUN go get -d -v -RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . +RUN go mod download + +# Copy the rest of the project to ensure code changes doesnt trigger re-download of all deps +COPY . . + +RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$GOARCH go build -a -installsuffix cgo -o main . ############################ @@ -33,8 +38,8 @@ COPY --from=builder /app/index index COPY --from=builder /app/docs docs # Set environment variables and expose necessary port -ENV PORT 8080 -ENV GIN_MODE release +ENV PORT=8080 +ENV GIN_MODE=release EXPOSE 8080 # Run the Go Gin binary diff --git a/cached.Dockerfile b/cached.Dockerfile new file mode 100644 index 00000000..9c9f30d1 --- /dev/null +++ b/cached.Dockerfile @@ -0,0 +1,53 @@ +############################ +# STEP 1 build executable binary +############################ +FROM --platform=$BUILDPLATFORM golang:alpine AS builder +# Install git. +RUN apk update && apk add --no-cache git=~2 + +# Set up working directory +WORKDIR /app +# Copy go.mod and go.sum separately so we only invalidate the downloading layers if we need to +COPY go.mod go.sum ./ + +# Fetch dependencies and build the binary +ENV GO111MODULE=on +RUN --mount=type=cache,target=/go/pkg/mod/ \ + --mount=type=bind,source=go.sum,target=go.sum \ + --mount=type=bind,source=go.mod,target=go.mod \ + go mod download -x + +# Copy the rest of the project to ensure code changes doesnt trigger re-download of all deps +COPY . . + +ENV GOCACHE=/root/.cache/go-build +RUN --mount=type=cache,target=/go/pkg/mod/ \ + --mount=type=cache,target="/root/.cache/go-build" \ + CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$GOARCH go build -a -installsuffix cgo -o main . + + +############################ +# STEP 2 build a small image +############################ +FROM alpine:3 + +# Set up the working directory +WORKDIR /go + +# Copy the binary from the builder stage +COPY --from=builder /app/main . + +# Copy the "index" folder +COPY --from=builder /app/index index + +# Copy the "docs" folder +COPY --from=builder /app/docs docs + +# Set environment variables and expose necessary port +ENV PORT=8080 +ENV GIN_MODE=release +EXPOSE 8080 + +# Run the Go Gin binary +ENTRYPOINT ["./main"] + From 9a9f35d8801e569b397ef142e435da028688eba0 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 19:14:56 +0100 Subject: [PATCH 18/36] update readme to reflect changes --- README.md | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index eef48487..1836908c 100644 --- a/README.md +++ b/README.md @@ -24,21 +24,11 @@ You can install a local development environment by following the [local environm Remember to run the tests before creating a pull request. -#### Acceptance Tests ```bash -go test ./test/acc/... -``` -#### End-to-End Tests -```bash -go build -o go-deploy . # Build -./go-deploy --mode=test # Start - -# Wait for the API to return 200 on /healthz -until $(curl --output /dev/null --silent --head --fail http://localhost:8080/healthz); do - echo "Waiting for API to start" - sleep 1 -done -go test ./test/e2e/... # Run e2e tests +make test +# or +# make acc +# make e2e ``` ## 📚 Docs @@ -46,13 +36,13 @@ go test ./test/e2e/... # Run e2e tests ### Codebase The code base is documented using godoc. You can view the documentation by running the documentation server locally. -1. Install godoc `go install golang.org/x/tools/cmd/godoc` +1. Install godoc `go install golang.org/x/tools/cmd/godoc@latest` 2. Run godoc `godoc -http=:6060` 3. Visit [http://localhost:6060/pkg/go-deploy/](http://localhost:6060/pkg/go-deploy/) ### API -The API is documented using OpenAPI 3.0 specification and is available at [https://api.cloud.cbh.kth.se/deploy/v2/docs/index.html](https://api.cloud.cbh.kth.se/deploy/v2/docs/index.html). +The API is documented using OpenAPI 3.1.0 specification and is available at [https://api.cloud.cbh.kth.se/deploy/v2/docs/index.html](https://api.cloud.cbh.kth.se/deploy/v2/docs/index.html). You can also run the API locally by [setting up the local environment](scripts/local/README.md) and visiting [http://localhost:8080/v2/docs/index.html](http://localhost:8080/v2/docs/index.html). From 993b5a14c6a9d889114e40f4bb94419b05a59762 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Mon, 20 Jan 2025 21:34:22 +0100 Subject: [PATCH 19/36] fix typo in openapi definition for delete storagemanager endpoint --- docs/api/v2/V2_docs.go | 2 +- docs/api/v2/V2_swagger.json | 2 +- docs/api/v2/V2_swagger.yaml | 48 ++++++++++++++++++++++++++++++++++++- routers/api/v2/sm.go | 2 +- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index 477a1c10..65edd86e 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -9,7 +9,7 @@ const docTemplateV2 = `{ "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"{{escape .Description}}","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"{{.Title}}","version":"{{.Version}}"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"get":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" }` diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index 62181d53..c129f8b0 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -2,6 +2,6 @@ "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"go-deploy API","version":"1.0"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"get":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" } \ No newline at end of file diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index cdf5400e..d90732c2 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -3099,7 +3099,7 @@ paths: tags: - StorageManager /v2/storageManagers/{storageManagerId}: - get: + delete: description: Delete storage manager parameters: - description: Storage manager ID @@ -3145,6 +3145,52 @@ paths: summary: Delete storage manager tags: - StorageManager + get: + description: Get storage manager + parameters: + - description: Storage manager ID + in: path + name: storageManagerId + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/body.SmDeleted' + description: OK + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Bad Request + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: Get storage manager + tags: + - StorageManager /v2/systemCapacities: get: description: List system capacities diff --git a/routers/api/v2/sm.go b/routers/api/v2/sm.go index d334556f..9cf12ec1 100644 --- a/routers/api/v2/sm.go +++ b/routers/api/v2/sm.go @@ -129,7 +129,7 @@ func ListSMs(c *gin.Context) { // @Failure 401 {object} sys.ErrorResponse // @Failure 404 {object} sys.ErrorResponse // @Failure 500 {object} sys.ErrorResponse -// @Router /v2/storageManagers/{storageManagerId} [get] +// @Router /v2/storageManagers/{storageManagerId} [delete] func DeleteSM(c *gin.Context) { context := sys.NewContext(c) From d85e48e4be84ed6c3e88292a0d1bc37c320381e1 Mon Sep 17 00:00:00 2001 From: Philip Zingmark <112874974+Phillezi@users.noreply.github.com> Date: Mon, 20 Jan 2025 23:27:14 +0100 Subject: [PATCH 20/36] Update generate-build-branch.yml remove call to removed script --- .github/workflows/generate-build-branch.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/generate-build-branch.yml b/.github/workflows/generate-build-branch.yml index a3ed6d5e..d01ad733 100644 --- a/.github/workflows/generate-build-branch.yml +++ b/.github/workflows/generate-build-branch.yml @@ -23,9 +23,7 @@ jobs: chmod +x ./generate-types.sh ./generate-types.sh chmod +x ./generate-docs.sh - ./generate-docs.sh - chmod +x ./convert-to-v3-docs.sh - ./convert-to-v3-docs.sh + ./generate-docs.sh cd .. echo "Cloning build branch" @@ -57,4 +55,4 @@ jobs: git push else echo "No changes to commit" - fi \ No newline at end of file + fi From 1d8a32eb10aecb34ec547f7f14dda6c0a5b975c5 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 21 Jan 2025 00:49:37 +0100 Subject: [PATCH 21/36] Fix openapi basepath when being served behind proxy --- docs/api/v2/handlers/serve_fs.go | 8 ++---- docs/api/v2/util/servers.go | 49 ++++++++++++++++++++++++++++++++ routers/router.go | 6 ++++ 3 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 docs/api/v2/util/servers.go diff --git a/docs/api/v2/handlers/serve_fs.go b/docs/api/v2/handlers/serve_fs.go index e41100cf..df93be48 100644 --- a/docs/api/v2/handlers/serve_fs.go +++ b/docs/api/v2/handlers/serve_fs.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/gin-gonic/gin" - "github.com/swaggo/swag/v2" + v2 "github.com/kthcloud/go-deploy/docs/api/v2" swaggerfiles "github.com/swaggo/files/v2" ) @@ -40,11 +40,7 @@ func ServeDocs(basePath string) func(ctx *gin.Context) { } if strings.TrimPrefix(filePath, "/") == "doc.json" { - doc, err := swag.ReadDoc("V2") - if err != nil { - ctx.String(http.StatusInternalServerError, "Failed to load documentation") - return - } + doc := v2.SwaggerInfoV2.ReadDoc() ctx.Header("Cache-Control", "public, max-age=3600") ctx.Data(http.StatusOK, "application/json", []byte(doc)) return diff --git a/docs/api/v2/util/servers.go b/docs/api/v2/util/servers.go new file mode 100644 index 00000000..26375738 --- /dev/null +++ b/docs/api/v2/util/servers.go @@ -0,0 +1,49 @@ +package util + +import ( + "fmt" + "strings" + + docsV2 "github.com/kthcloud/go-deploy/docs/api/v2" + + "github.com/swaggo/swag/v2" +) + +type ExtendedSpec struct { + swag.Spec + Servers []struct { + URL string `json:"url"` + Description string `json:"description,omitempty"` + } `json:"servers,omitempty"` +} + +func UpdateSwaggerServers(servers ...string) error { + // Create the server JSON part dynamically + var serversJSON string + for _, server := range servers { + serversJSON += fmt.Sprintf(` + { + "url": "%s", + "description": "" + },`, server) + } + + // Remove the last comma (to make it valid JSON) and add it in the correct location + if len(serversJSON) > 0 { + serversJSON = serversJSON[:len(serversJSON)-1] + } + + // Find the last closing brace in the Swagger template and inject servers JSON before it + swaggerTemplate := docsV2.SwaggerInfoV2.SwaggerTemplate + closeBraceIndex := strings.LastIndex(swaggerTemplate, "}") + if closeBraceIndex == -1 { + return fmt.Errorf("could not find closing brace in Swagger template") + } + + // Insert the servers JSON right before the closing brace + swaggerTemplate = swaggerTemplate[:closeBraceIndex] + ",\n \"servers\": [" + serversJSON + "]" + swaggerTemplate[closeBraceIndex:] + + // Update the Swagger template + docsV2.SwaggerInfoV2.SwaggerTemplate = swaggerTemplate + return nil +} diff --git a/routers/router.go b/routers/router.go index 1a3914c2..7d4b2373 100644 --- a/routers/router.go +++ b/routers/router.go @@ -13,6 +13,7 @@ import ( "github.com/go-playground/validator/v10" docsV2 "github.com/kthcloud/go-deploy/docs/api/v2" docsV2Handlers "github.com/kthcloud/go-deploy/docs/api/v2/handlers" + docsV2ServerUtil "github.com/kthcloud/go-deploy/docs/api/v2/util" "github.com/kthcloud/go-deploy/models/mode" "github.com/kthcloud/go-deploy/pkg/auth" "github.com/kthcloud/go-deploy/pkg/config" @@ -70,6 +71,11 @@ func NewRouter() *gin.Engine { docsV2.SwaggerInfoV2.Host = "" docsV2.SwaggerInfoV2.Schemes = []string{"http", "https"} + // Update openapi spec to have the correct basepath, since openapi 3.+ doesnt use basepath and uses servers instead + if err := docsV2ServerUtil.UpdateSwaggerServers(basePath); err != nil { + log.Fatalln(err) + } + //public.GET("/v2/docs/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) public.GET("/v2/docs/*any", docsV2Handlers.ServeDocs(basePath+"/v2/docs")) //// Health check routes From 568db31fbcc6838806de9235e2397a44e761b6bf Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Thu, 23 Jan 2025 18:21:55 +0100 Subject: [PATCH 22/36] Added field for neverStale, which admins can change on deployments and vms --- docs/api/v2/V2_docs.go | 4 +- docs/api/v2/V2_swagger.json | 4 +- docs/api/v2/V2_swagger.yaml | 56 +++++++++++++++++++ dto/v2/body/deployment.go | 7 +++ dto/v2/body/vm.go | 13 +++-- export/types/v2/body/index.ts | 9 +++ models/model/deployment.go | 2 + models/model/deployment_convert.go | 8 ++- models/model/deployment_params.go | 4 ++ models/model/vm.go | 2 + models/model/vm_convert.go | 7 ++- models/model/vm_params.go | 3 + pkg/db/resources/deployment_repo/db.go | 3 + pkg/db/resources/vm_repo/db.go | 3 + .../cleaner/stale_resource_cleaner.go | 7 ++- routers/api/v2/deployment.go | 15 +++++ routers/api/v2/resource_migration.go | 5 -- routers/api/v2/vm.go | 12 ++++ 18 files changed, 146 insertions(+), 18 deletions(-) diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index 65edd86e..490aa50d 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -6,10 +6,10 @@ import "github.com/swaggo/swag/v2" const docTemplateV2 = `{ "schemes": {{ marshal .Schemes }}, - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"{{escape .Description}}","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"{{.Title}}","version":"{{.Version}}"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" }` diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index c129f8b0..9f02b41e 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -1,7 +1,7 @@ { - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"go-deploy API","version":"1.0"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" } \ No newline at end of file diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index d90732c2..8f47b029 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -161,6 +161,10 @@ components: maxLength: 30 minLength: 3 type: string + neverStale: + description: Boolean to make deployment never get disabled, despite being + stale + type: boolean private: description: 'Deprecated: Use Visibility instead.' type: boolean @@ -242,6 +246,8 @@ components: type: integer name: type: string + neverStale: + type: boolean ownerId: type: string pingResult: @@ -333,6 +339,8 @@ components: maxLength: 30 minLength: 3 type: string + neverStale: + type: boolean private: description: 'Deprecated: Use Visibility instead.' type: boolean @@ -1352,6 +1360,8 @@ components: maxLength: 30 minLength: 3 type: string + neverStale: + type: boolean ports: items: $ref: '#/components/schemas/body.PortCreate' @@ -1433,6 +1443,8 @@ components: type: string name: type: string + neverStale: + type: boolean ownerId: type: string ports: @@ -1503,6 +1515,8 @@ components: maxLength: 30 minLength: 3 type: string + neverStale: + type: boolean ports: items: $ref: '#/components/schemas/body.PortUpdate' @@ -1700,6 +1714,18 @@ paths: schema: $ref: '#/components/schemas/sys.ErrorResponse' description: Bad Request + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Forbidden + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found "500": content: application/json: @@ -1746,6 +1772,12 @@ paths: schema: $ref: '#/components/schemas/sys.ErrorResponse' description: Unauthorized + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Forbidden "404": content: application/json: @@ -1827,6 +1859,18 @@ paths: schema: $ref: '#/components/schemas/sys.ErrorResponse' description: Bad Request + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Forbidden + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Not Found "500": content: application/json: @@ -3814,6 +3858,12 @@ paths: schema: $ref: '#/components/schemas/sys.ErrorResponse' description: Unauthorized + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Forbidden "404": content: application/json: @@ -3959,6 +4009,12 @@ paths: schema: $ref: '#/components/schemas/sys.ErrorResponse' description: Unauthorized + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Forbidden "404": content: application/json: diff --git a/dto/v2/body/deployment.go b/dto/v2/body/deployment.go index a5aa0ff7..b770676b 100644 --- a/dto/v2/body/deployment.go +++ b/dto/v2/body/deployment.go @@ -30,6 +30,8 @@ type DeploymentRead struct { CustomDomain *CustomDomainRead `json:"customDomain,omitempty"` Visibility string `json:"visibility"` + NeverStale bool `json:"neverStale" bson:"neverStale" binding:"omitempty,boolean"` + // Deprecated: Use Visibility instead. Private bool `json:"private"` @@ -60,6 +62,9 @@ type DeploymentCreate struct { Args []string `json:"args" bson:"args" binding:"omitempty,min=0,max=100,dive,min=0,max=100"` Visibility string `json:"visibility" bson:"visibility" binding:"omitempty,oneof=public private auth"` + // Boolean to make deployment never get disabled, despite being stale + NeverStale bool `json:"neverStale" bson:"neverStale" binding:"omitempty,boolean"` + // Deprecated: Use Visibility instead. Private bool `json:"private" bson:"private" binding:"omitempty,boolean"` @@ -87,6 +92,8 @@ type DeploymentUpdate struct { Args *[]string `json:"args,omitempty" bson:"args,omitempty" binding:"omitempty,min=0,max=100,dive,min=0,max=100"` Visibility *string `json:"visibility" bson:"visibility" binding:"omitempty,oneof=public private auth"` + NeverStale *bool `json:"neverStale,omitempty" bson:"neverStale" binding:"omitempty,boolean"` + // Deprecated: Use Visibility instead. Private *bool `json:"private,omitempty" bson:"private,omitempty" binding:"omitempty,boolean"` diff --git a/dto/v2/body/vm.go b/dto/v2/body/vm.go index 80766dd3..30c3688f 100644 --- a/dto/v2/body/vm.go +++ b/dto/v2/body/vm.go @@ -15,6 +15,8 @@ type VmRead struct { RepairedAt *time.Time `json:"repairedAt,omitempty"` AccessedAt time.Time `json:"accessedAt"` + NeverStale bool `json:"neverStale"` + Specs VmSpecs `json:"specs"` Ports []PortRead `json:"ports"` GPU *VmGpuLease `json:"gpu,omitempty"` @@ -36,13 +38,16 @@ type VmCreate struct { DiskSize int `json:"diskSize" bson:"diskSize" binding:"required,min=10"` Zone *string `json:"zone,omitempty" bson:"zone,omitempty" binding:"omitempty"` + + NeverStale bool `json:"neverStale" bson:"neverStale" binding:"omitempty,boolean"` } type VmUpdate struct { - Name *string `json:"name,omitempty" bson:"name,omitempty" binding:"omitempty,rfc1035,min=3,max=30,vm_name"` - Ports *[]PortUpdate `json:"ports,omitempty" bson:"ports,omitempty" binding:"omitempty,port_list_names,port_list_numbers,port_list_http_proxies,min=0,max=10,dive"` - CpuCores *int `json:"cpuCores,omitempty" bson:"cpuCores,omitempty" binding:"omitempty,min=1"` - RAM *int `json:"ram,omitempty" bson:"ram,omitempty" binding:"omitempty,min=1"` + Name *string `json:"name,omitempty" bson:"name,omitempty" binding:"omitempty,rfc1035,min=3,max=30,vm_name"` + Ports *[]PortUpdate `json:"ports,omitempty" bson:"ports,omitempty" binding:"omitempty,port_list_names,port_list_numbers,port_list_http_proxies,min=0,max=10,dive"` + CpuCores *int `json:"cpuCores,omitempty" bson:"cpuCores,omitempty" binding:"omitempty,min=1"` + RAM *int `json:"ram,omitempty" bson:"ram,omitempty" binding:"omitempty,min=1"` + NeverStale *bool `json:"neverStale,omitempty" bson:"neverStale" binding:"omitempty,boolean"` } type VmUpdateOwner struct { diff --git a/export/types/v2/body/index.ts b/export/types/v2/body/index.ts index 6bfbacd6..ef1e853e 100644 --- a/export/types/v2/body/index.ts +++ b/export/types/v2/body/index.ts @@ -45,6 +45,7 @@ export interface DeploymentRead { healthCheckPath?: string; customDomain?: CustomDomainRead; visibility: string; + neverStale: boolean; /** * Deprecated: Use Visibility instead. */ @@ -71,6 +72,10 @@ export interface DeploymentCreate { initCommands: string[]; args: string[]; visibility: string; + /** + * Boolean to make deployment never get disabled, despite being stale + */ + neverStale: boolean; /** * Deprecated: Use Visibility instead. */ @@ -98,6 +103,7 @@ export interface DeploymentUpdate { initCommands?: string[]; args?: string[]; visibility?: string; + neverStale?: boolean; /** * Deprecated: Use Visibility instead. */ @@ -759,6 +765,7 @@ export interface VmRead { updatedAt?: string; repairedAt?: string; accessedAt: string; + neverStale: boolean; specs: VmSpecs; ports: PortRead[]; gpu?: VmGpuLease; @@ -775,12 +782,14 @@ export interface VmCreate { ram: number /* int */; diskSize: number /* int */; zone?: string; + neverStale: boolean; } export interface VmUpdate { name?: string; ports?: PortUpdate[]; cpuCores?: number /* int */; ram?: number /* int */; + neverStale?: boolean; } export interface VmUpdateOwner { newOwnerId: string; diff --git a/models/model/deployment.go b/models/model/deployment.go index fc1f1f22..59f1e8fb 100644 --- a/models/model/deployment.go +++ b/models/model/deployment.go @@ -23,6 +23,8 @@ type Deployment struct { DeletedAt time.Time `bson:"deletedAt"` AccessedAt time.Time `bson:"accessedAt"` + NeverStale bool `bson:"neverStale"` + Activities map[string]Activity `bson:"activities"` Apps map[string]App `bson:"apps"` diff --git a/models/model/deployment_convert.go b/models/model/deployment_convert.go index 58c2610a..b7290195 100644 --- a/models/model/deployment_convert.go +++ b/models/model/deployment_convert.go @@ -2,11 +2,12 @@ package model import ( "fmt" + "strconv" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/utils" "golang.org/x/net/idna" - "strconv" ) // ToDTO converts a Deployment to a body.DeploymentRead DTO. @@ -129,6 +130,8 @@ func (deployment *Deployment) ToDTO(smURL *string, externalPort *int, teams []st CustomDomain: customDomain, Visibility: app.Visibility, + NeverStale: deployment.NeverStale, + Status: status, Error: deploymentError, ReplicaStatus: replicaStatus, @@ -222,6 +225,8 @@ func (p *DeploymentCreateParams) FromDTO(dto *body.DeploymentCreate, fallbackZon } else { p.Visibility = dto.Visibility } + + p.NeverStale = dto.NeverStale } // FromDTO converts body.DeploymentUpdate DTO to DeploymentUpdateParams. @@ -277,4 +282,5 @@ func (p *DeploymentUpdateParams) FromDTO(dto *body.DeploymentUpdate, deploymentT p.PingPath = dto.HealthCheckPath p.Replicas = dto.Replicas p.Visibility = dto.Visibility + p.NeverStale = dto.NeverStale } diff --git a/models/model/deployment_params.go b/models/model/deployment_params.go index 9d2f0892..d94dc569 100644 --- a/models/model/deployment_params.go +++ b/models/model/deployment_params.go @@ -18,6 +18,8 @@ type DeploymentCreateParams struct { CustomDomain *string Visibility string + NeverStale bool + Zone string } @@ -38,6 +40,8 @@ type DeploymentUpdateParams struct { PingPath *string Replicas *int Visibility *string + + NeverStale *bool } type DeploymentUpdateOwnerParams struct { diff --git a/models/model/vm.go b/models/model/vm.go index 8f61d31d..5965ddd4 100644 --- a/models/model/vm.go +++ b/models/model/vm.go @@ -18,6 +18,8 @@ type VM struct { DeletedAt time.Time `bson:"deletedAt,omitempty"` AccessedAt time.Time `bson:"accessedAt"` + NeverStale bool `bson:"neverStale"` + SshPublicKey string `bson:"sshPublicKey"` PortMap map[string]Port `bson:"portMap"` Specs VmSpecs `bson:"specs"` diff --git a/models/model/vm_convert.go b/models/model/vm_convert.go index d12a161c..2b820e00 100644 --- a/models/model/vm_convert.go +++ b/models/model/vm_convert.go @@ -2,10 +2,11 @@ package model import ( "fmt" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/subsystems" "github.com/kthcloud/go-deploy/utils" - "time" ) // ToDTOv2 converts a VM to a body.VmRead. @@ -91,6 +92,8 @@ func (vm *VM) ToDTOv2(gpuLease *GpuLease, teams []string, externalPort *int, ssh RepairedAt: utils.NonZeroOrNil(vm.RepairedAt), AccessedAt: vm.AccessedAt, + NeverStale: vm.NeverStale, + Specs: body.VmSpecs{ CpuCores: vm.Specs.CpuCores, RAM: vm.Specs.RAM, @@ -113,6 +116,7 @@ func (p VmCreateParams) FromDTOv2(dto *body.VmCreate, fallbackZone *string) VmCr p.RAM = dto.RAM p.DiskSize = dto.DiskSize p.PortMap = make(map[string]PortCreateParams) + p.NeverStale = dto.NeverStale if dto.Zone == nil { p.Zone = *fallbackZone @@ -147,6 +151,7 @@ func (p VmUpdateParams) FromDTOv2(dto *body.VmUpdate) VmUpdateParams { p.Name = dto.Name p.CpuCores = dto.CpuCores p.RAM = dto.RAM + p.NeverStale = dto.NeverStale if dto.Ports != nil { portMap := make(map[string]PortUpdateParams) diff --git a/models/model/vm_params.go b/models/model/vm_params.go index 79c1d070..8fe35e63 100644 --- a/models/model/vm_params.go +++ b/models/model/vm_params.go @@ -17,6 +17,8 @@ type VmCreateParams struct { CpuCores int RAM int DiskSize int + + NeverStale bool } type VmUpdateParams struct { @@ -26,6 +28,7 @@ type VmUpdateParams struct { PortMap *map[string]PortUpdateParams CpuCores *int RAM *int + NeverStale *bool } type VmUpdateOwnerParams struct { diff --git a/pkg/db/resources/deployment_repo/db.go b/pkg/db/resources/deployment_repo/db.go index ae8b637d..a34b50bc 100644 --- a/pkg/db/resources/deployment_repo/db.go +++ b/pkg/db/resources/deployment_repo/db.go @@ -69,6 +69,8 @@ func (client *Client) Create(id, ownerID string, params *model.DeploymentCreateP DeletedAt: time.Time{}, AccessedAt: time.Now(), + NeverStale: params.NeverStale, + Activities: map[string]model.Activity{model.ActivityBeingCreated: { Name: model.ActivityBeingCreated, CreatedAt: time.Now(), @@ -141,6 +143,7 @@ func (client *Client) UpdateWithParams(id string, params *model.DeploymentUpdate db.AddIfNotNil(&setUpdate, "apps.main.ram", params.RAM) db.AddIfNotNil(&setUpdate, "apps.main.replicas", params.Replicas) db.AddIfNotNil(&setUpdate, "apps.main.visibility", params.Visibility) + db.AddIfNotNil(&setUpdate, "neverStale", params.NeverStale) err = client.UpdateWithBsonByID(id, bson.D{ diff --git a/pkg/db/resources/vm_repo/db.go b/pkg/db/resources/vm_repo/db.go index 72881434..41cf241e 100644 --- a/pkg/db/resources/vm_repo/db.go +++ b/pkg/db/resources/vm_repo/db.go @@ -57,6 +57,8 @@ func (client *Client) Create(id, owner string, params *model.VmCreateParams) (*m DeletedAt: time.Time{}, AccessedAt: time.Now(), + NeverStale: params.NeverStale, + SshPublicKey: params.SshPublicKey, PortMap: portMap, Specs: model.VmSpecs{ @@ -220,6 +222,7 @@ func (client *Client) UpdateWithParams(id string, params *model.VmUpdateParams) db.AddIfNotNil(&setUpdate, "ownerId", params.OwnerID) db.AddIfNotNil(&setUpdate, "specs.cpuCores", params.CpuCores) db.AddIfNotNil(&setUpdate, "specs.ram", params.RAM) + db.AddIfNotNil(&setUpdate, "neverStale", params.NeverStale) err := client.UpdateWithBsonByID(id, bson.D{ diff --git a/pkg/services/cleaner/stale_resource_cleaner.go b/pkg/services/cleaner/stale_resource_cleaner.go index 549bbaf9..32c52902 100644 --- a/pkg/services/cleaner/stale_resource_cleaner.go +++ b/pkg/services/cleaner/stale_resource_cleaner.go @@ -1,6 +1,8 @@ package cleaner import ( + "time" + bodyV2 "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/models/version" @@ -10,7 +12,6 @@ import ( "github.com/kthcloud/go-deploy/pkg/log" "github.com/kthcloud/go-deploy/pkg/subsystems" "github.com/kthcloud/go-deploy/service" - "time" ) func staleResourceCleaner() error { @@ -21,7 +22,7 @@ func staleResourceCleaner() error { } for _, deployment := range deployments { - if deployment.GetMainApp().Replicas == 0 { + if deployment.NeverStale || deployment.GetMainApp().Replicas == 0 { continue } @@ -53,7 +54,7 @@ func staleResourceCleaner() error { } for _, vm := range vms { - if k8sVM := &vm.Subsystems.K8s.VM; subsystems.NotCreated(k8sVM) || !k8sVM.Running { + if k8sVM := &vm.Subsystems.K8s.VM; vm.NeverStale || subsystems.NotCreated(k8sVM) || !k8sVM.Running { continue } diff --git a/routers/api/v2/deployment.go b/routers/api/v2/deployment.go index 46756dee..debff7b1 100644 --- a/routers/api/v2/deployment.go +++ b/routers/api/v2/deployment.go @@ -153,6 +153,8 @@ func ListDeployments(c *gin.Context) { // @Param body body body.DeploymentCreate true "Deployment body" // @Success 200 {object} body.DeploymentRead // @Failure 400 {object} sys.ErrorResponse +// @Failure 404 {object} sys.ErrorResponse +// @Failure 403 {object} sys.ErrorResponse // @Failure 500 {object} sys.ErrorResponse // @Router /v2/deployments [post] func CreateDeployment(c *gin.Context) { @@ -212,6 +214,11 @@ func CreateDeployment(c *gin.Context) { return } + if requestBody.NeverStale && !auth.User.IsAdmin { + context.Forbidden("User is not allowed to create deployment with neverStale attribute set as true") + return + } + err = deployV2.Deployments().CheckQuota("", &opts.QuotaOptions{Create: &requestBody}) if err != nil { var quotaExceededErr sErrors.QuotaExceededError @@ -257,6 +264,7 @@ func CreateDeployment(c *gin.Context) { // @Failure 400 {object} sys.ErrorResponse // @Failure 401 {object} sys.ErrorResponse // @Failure 404 {object} sys.ErrorResponse +// @Failure 403 {object} sys.ErrorResponse // @Failure 500 {object} sys.ErrorResponse // @Router /v2/deployments/{deploymentId} [delete] func DeleteDeployment(c *gin.Context) { @@ -338,6 +346,8 @@ func DeleteDeployment(c *gin.Context) { // @Param body body body.DeploymentUpdate true "Deployment update" // @Success 200 {object} body.DeploymentUpdated // @Failure 400 {object} sys.ErrorResponse +// @Failure 404 {object} sys.ErrorResponse +// @Failure 403 {object} sys.ErrorResponse // @Failure 500 {object} sys.ErrorResponse // @Router /v2/deployments/{deploymentId} [post] func UpdateDeployment(c *gin.Context) { @@ -386,6 +396,11 @@ func UpdateDeployment(c *gin.Context) { } } + if requestBody.NeverStale != nil && !auth.User.IsAdmin { + context.Forbidden("User is not allowed to modify the neverStale value") + return + } + err = deployV2.Deployments().CheckQuota(requestURI.DeploymentID, &opts.QuotaOptions{Update: &requestBody}) if err != nil { var quotaExceededErr sErrors.QuotaExceededError diff --git a/routers/api/v2/resource_migration.go b/routers/api/v2/resource_migration.go index 456fca12..25aaa698 100644 --- a/routers/api/v2/resource_migration.go +++ b/routers/api/v2/resource_migration.go @@ -321,10 +321,5 @@ func DeleteResourceMigration(c *gin.Context) { return } - if err != nil { - context.ServerError(err, ErrInternal) - return - } - context.OkNoContent() } diff --git a/routers/api/v2/vm.go b/routers/api/v2/vm.go index c0a490c8..b7087195 100644 --- a/routers/api/v2/vm.go +++ b/routers/api/v2/vm.go @@ -161,6 +161,7 @@ func ListVMs(c *gin.Context) { // @Success 200 {object} body.VmCreated // @Failure 400 {object} sys.ErrorResponse // @Failure 401 {object} sys.ErrorResponse +// @Failure 403 {object} sys.ErrorResponse // @Failure 404 {object} sys.ErrorResponse // @Failure 500 {object} sys.ErrorResponse // @Router /v2/vms [post] @@ -210,6 +211,11 @@ func CreateVM(c *gin.Context) { } } + if requestBody.NeverStale && !auth.User.IsAdmin { + context.Forbidden("User is not allowed to create VM with neverStale attribute set as true") + return + } + err = deployV2.VMs().CheckQuota("", auth.User.ID, &auth.GetEffectiveRole().Quotas, opts.QuotaOpts{Create: &requestBody}) if err != nil { var quotaExceedErr sErrors.QuotaExceededError @@ -318,6 +324,7 @@ func DeleteVM(c *gin.Context) { // @Success 200 {object} body.VmUpdated // @Failure 400 {object} sys.ErrorResponse // @Failure 401 {object} sys.ErrorResponse +// @Failure 403 {object} sys.ErrorResponse // @Failure 404 {object} sys.ErrorResponse // @Failure 500 {object} sys.ErrorResponse // @Router /v2/vms/{vmId} [post] @@ -386,6 +393,11 @@ func UpdateVM(c *gin.Context) { } } + if requestBody.NeverStale != nil && !auth.User.IsAdmin { + context.Forbidden("User is not allowed to modify the neverStale value") + return + } + err = deployV2.VMs().CheckQuota(vm.ID, auth.User.ID, &auth.GetEffectiveRole().Quotas, opts.QuotaOpts{Update: &requestBody}) if err != nil { var quotaExceededErr sErrors.QuotaExceededError From 0cac3ef13ec84e0f0b9a894d0ff86c24d213d6bb Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Fri, 24 Jan 2025 00:32:46 +0100 Subject: [PATCH 23/36] added endpoint for verbose host information for troubleshooting --- docs/api/v2/V2_docs.go | 4 +-- docs/api/v2/V2_swagger.json | 4 +-- docs/api/v2/V2_swagger.yaml | 54 +++++++++++++++++++++++++++++++++++ dto/v2/body/host.go | 13 +++++++++ export/types/v2/body/index.ts | 9 ++++++ models/model/host.go | 18 +++++++++++- routers/api/v2/hosts.go | 36 ++++++++++++++++++++++- routers/routes/host.go | 11 +++++-- test/temp_test.go | 14 +++++++++ 9 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 test/temp_test.go diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index 490aa50d..6e86409f 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -6,10 +6,10 @@ import "github.com/swaggo/swag/v2" const docTemplateV2 = `{ "schemes": {{ marshal .Schemes }}, - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"{{escape .Description}}","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"{{.Title}}","version":"{{.Version}}"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/hosts/verbose":{"get":{"description":"List Hosts verbose","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostVerboseRead"},"type":"array"}}},"description":"OK"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List Hosts verbose","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" }` diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index 9f02b41e..bd5358b1 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -1,7 +1,7 @@ { - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"go-deploy API","version":"1.0"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/hosts/verbose":{"get":{"description":"List Hosts verbose","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostVerboseRead"},"type":"array"}}},"description":"OK"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List Hosts verbose","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" } \ No newline at end of file diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index 8f47b029..9dc5f5c9 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -597,6 +597,30 @@ components: description: Zone is the name of the zone where the host is located. type: string type: object + body.HostVerboseRead: + properties: + deactivatedUntil: + type: string + displayName: + type: string + enabled: + type: boolean + ip: + type: string + lastSeenAt: + type: string + name: + type: string + port: + type: integer + registeredAt: + type: string + schedulable: + type: boolean + zone: + description: Zone is the name of the zone where the host is located. + type: string + type: object body.HttpProxyCreate: properties: customDomain: @@ -2437,6 +2461,36 @@ paths: summary: List Hosts tags: - Host + /v2/hosts/verbose: + get: + description: List Hosts verbose + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.HostVerboseRead' + type: array + description: OK + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Forbidden + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List Hosts verbose + tags: + - Host /v2/jobs: get: description: List jobs diff --git a/dto/v2/body/host.go b/dto/v2/body/host.go index 613bcfec..499dedb5 100644 --- a/dto/v2/body/host.go +++ b/dto/v2/body/host.go @@ -1,9 +1,22 @@ package body +import "time" + type HostRead struct { HostBase `json:",inline" tstype:",extends"` } +type HostVerboseRead struct { + HostBase `json:",inline" tstype:",extends"` + IP string `json:"ip"` + Port int `json:"port"` + Enabled bool `json:"enabled"` + Schedulable bool `json:"schedulable"` + DeactivatedUntil *time.Time `json:"deactivatedUntil,omitempty"` + LastSeenAt time.Time `json:"lastSeenAt"` + RegisteredAt time.Time `json:"registeredAt"` +} + type HostBase struct { Name string `json:"name"` DisplayName string `json:"displayName"` diff --git a/export/types/v2/body/index.ts b/export/types/v2/body/index.ts index ef1e853e..3f4f0f47 100644 --- a/export/types/v2/body/index.ts +++ b/export/types/v2/body/index.ts @@ -282,6 +282,15 @@ export interface GpuLeaseDeleted { export interface HostRead extends HostBase { } +export interface HostVerboseRead extends HostBase { + ip: string; + port: number /* int */; + enabled: boolean; + schedulable: boolean; + deactivatedUntil?: string; + lastSeenAt: string; + registeredAt: string; +} export interface HostBase { name: string; displayName: string; diff --git a/models/model/host.go b/models/model/host.go index 77d8fb8e..575d865c 100644 --- a/models/model/host.go +++ b/models/model/host.go @@ -2,8 +2,9 @@ package model import ( "fmt" - "github.com/kthcloud/go-deploy/dto/v2/body" "time" + + "github.com/kthcloud/go-deploy/dto/v2/body" ) type Host struct { @@ -38,6 +39,21 @@ func (host *Host) ToDTO() body.HostRead { }, } } +func (host *Host) ToVerboseDTO() body.HostVerboseRead { + return body.HostVerboseRead{ + HostBase: body.HostBase{ + Name: host.Name, + DisplayName: host.DisplayName, + Zone: host.Zone, + }, + IP: host.IP, + Port: host.Port, + Enabled: host.Enabled, + Schedulable: host.Schedulable, + DeactivatedUntil: host.DeactivatedUntil, + RegisteredAt: host.RegisteredAt, + } +} func NewHostByParams(params *body.HostRegisterParams) *Host { return &Host{ Name: params.Name, diff --git a/routers/api/v2/hosts.go b/routers/api/v2/hosts.go index 838918fd..850c328b 100644 --- a/routers/api/v2/hosts.go +++ b/routers/api/v2/hosts.go @@ -24,11 +24,45 @@ func ListHosts(c *gin.Context) { if err != nil { context.ServerError(err, fmt.Errorf("failed to get host info")) } - dtoHosts := make([]body.HostRead, 0) for _, host := range hostInfo { dtoHosts = append(dtoHosts, host.ToDTO()) } + context.JSONResponse(200, dtoHosts) +} + +// VerboseListHosts +// @Summary List Hosts verbose +// @Description List Hosts verbose +// @Tags Host +// @Produce json +// @Security ApiKeyAuth +// @Security KeycloakOAuth +// @Success 200 {array} body.HostVerboseRead +// @Failure 403 {object} sys.ErrorResponse +// @Failure 500 {object} sys.ErrorResponse +// @Router /v2/hosts/verbose [get] +func VerboseListHosts(c *gin.Context) { + context := sys.NewContext(c) + auth, err := WithAuth(&context) + if err != nil { + context.ServerError(err, ErrAuthInfoNotAvailable) + return + } + + if (auth != nil && !auth.User.IsAdmin) || auth == nil { + context.Forbidden("Not permitted to request verbose host information") + return + } + + hostInfo, err := service.V2().System().ListHosts() + if err != nil { + context.ServerError(err, fmt.Errorf("failed to get host info")) + } + dtoHosts := make([]body.HostVerboseRead, 0) + for _, host := range hostInfo { + dtoHosts = append(dtoHosts, host.ToVerboseDTO()) + } context.JSONResponse(200, dtoHosts) } diff --git a/routers/routes/host.go b/routers/routes/host.go index 1809642a..7442ba02 100644 --- a/routers/routes/host.go +++ b/routers/routes/host.go @@ -3,8 +3,9 @@ package routes import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( - HostsPath = "/v2/hosts" - HostPath = "/v2/hosts/:hostId" + HostsPath = "/v2/hosts" + HostsPathVerbose = "/v2/hosts/verbose" + HostPath = "/v2/hosts/:hostId" ) type HostRoutingGroup struct{ RoutingGroupBase } @@ -18,3 +19,9 @@ func (group *HostRoutingGroup) PublicRoutes() []Route { {Method: "GET", Pattern: HostsPath, HandlerFunc: v2.ListHosts}, } } + +func (group *HostRoutingGroup) PrivateRoutes() []Route { + return []Route{ + {Method: "GET", Pattern: HostsPathVerbose, HandlerFunc: v2.VerboseListHosts}, + } +} diff --git a/test/temp_test.go b/test/temp_test.go new file mode 100644 index 00000000..34f9cd03 --- /dev/null +++ b/test/temp_test.go @@ -0,0 +1,14 @@ +package test + +import ( + "errors" + "testing" + + er "github.com/kthcloud/go-deploy/pkg/services/errors" +) + +func TestList(t *testing.T) { + if errors.Is(er.NewHostsFailedErr([]string{"t01n14", "t01n16"}), er.ErrNoHosts) { + t.Fail() + } +} From 141ae0b306e7684a0e1f12f32eb5f3ea4b4d0b78 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Fri, 24 Jan 2025 00:32:46 +0100 Subject: [PATCH 24/36] added endpoint for verbose host information for troubleshooting --- docs/api/v2/V2_docs.go | 4 +-- docs/api/v2/V2_swagger.json | 4 +-- docs/api/v2/V2_swagger.yaml | 54 +++++++++++++++++++++++++++++++++++ dto/v2/body/host.go | 13 +++++++++ export/types/v2/body/index.ts | 9 ++++++ models/model/host.go | 18 +++++++++++- routers/api/v2/hosts.go | 36 ++++++++++++++++++++++- routers/routes/host.go | 11 +++++-- 8 files changed, 141 insertions(+), 8 deletions(-) diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index 490aa50d..6e86409f 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -6,10 +6,10 @@ import "github.com/swaggo/swag/v2" const docTemplateV2 = `{ "schemes": {{ marshal .Schemes }}, - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"{{escape .Description}}","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"{{.Title}}","version":"{{.Version}}"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/hosts/verbose":{"get":{"description":"List Hosts verbose","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostVerboseRead"},"type":"array"}}},"description":"OK"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List Hosts verbose","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" }` diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index 9f02b41e..bd5358b1 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -1,7 +1,7 @@ { - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"go-deploy API","version":"1.0"}, "externalDocs": {"description":"","url":""}, - "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, + "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/hosts/verbose":{"get":{"description":"List Hosts verbose","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostVerboseRead"},"type":"array"}}},"description":"OK"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List Hosts verbose","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, "openapi": "3.1.0" } \ No newline at end of file diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index 8f47b029..9dc5f5c9 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -597,6 +597,30 @@ components: description: Zone is the name of the zone where the host is located. type: string type: object + body.HostVerboseRead: + properties: + deactivatedUntil: + type: string + displayName: + type: string + enabled: + type: boolean + ip: + type: string + lastSeenAt: + type: string + name: + type: string + port: + type: integer + registeredAt: + type: string + schedulable: + type: boolean + zone: + description: Zone is the name of the zone where the host is located. + type: string + type: object body.HttpProxyCreate: properties: customDomain: @@ -2437,6 +2461,36 @@ paths: summary: List Hosts tags: - Host + /v2/hosts/verbose: + get: + description: List Hosts verbose + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/body.HostVerboseRead' + type: array + description: OK + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Forbidden + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/sys.ErrorResponse' + description: Internal Server Error + security: + - ApiKeyAuth: [] + - KeycloakOAuth: [] + summary: List Hosts verbose + tags: + - Host /v2/jobs: get: description: List jobs diff --git a/dto/v2/body/host.go b/dto/v2/body/host.go index 613bcfec..499dedb5 100644 --- a/dto/v2/body/host.go +++ b/dto/v2/body/host.go @@ -1,9 +1,22 @@ package body +import "time" + type HostRead struct { HostBase `json:",inline" tstype:",extends"` } +type HostVerboseRead struct { + HostBase `json:",inline" tstype:",extends"` + IP string `json:"ip"` + Port int `json:"port"` + Enabled bool `json:"enabled"` + Schedulable bool `json:"schedulable"` + DeactivatedUntil *time.Time `json:"deactivatedUntil,omitempty"` + LastSeenAt time.Time `json:"lastSeenAt"` + RegisteredAt time.Time `json:"registeredAt"` +} + type HostBase struct { Name string `json:"name"` DisplayName string `json:"displayName"` diff --git a/export/types/v2/body/index.ts b/export/types/v2/body/index.ts index ef1e853e..3f4f0f47 100644 --- a/export/types/v2/body/index.ts +++ b/export/types/v2/body/index.ts @@ -282,6 +282,15 @@ export interface GpuLeaseDeleted { export interface HostRead extends HostBase { } +export interface HostVerboseRead extends HostBase { + ip: string; + port: number /* int */; + enabled: boolean; + schedulable: boolean; + deactivatedUntil?: string; + lastSeenAt: string; + registeredAt: string; +} export interface HostBase { name: string; displayName: string; diff --git a/models/model/host.go b/models/model/host.go index 77d8fb8e..575d865c 100644 --- a/models/model/host.go +++ b/models/model/host.go @@ -2,8 +2,9 @@ package model import ( "fmt" - "github.com/kthcloud/go-deploy/dto/v2/body" "time" + + "github.com/kthcloud/go-deploy/dto/v2/body" ) type Host struct { @@ -38,6 +39,21 @@ func (host *Host) ToDTO() body.HostRead { }, } } +func (host *Host) ToVerboseDTO() body.HostVerboseRead { + return body.HostVerboseRead{ + HostBase: body.HostBase{ + Name: host.Name, + DisplayName: host.DisplayName, + Zone: host.Zone, + }, + IP: host.IP, + Port: host.Port, + Enabled: host.Enabled, + Schedulable: host.Schedulable, + DeactivatedUntil: host.DeactivatedUntil, + RegisteredAt: host.RegisteredAt, + } +} func NewHostByParams(params *body.HostRegisterParams) *Host { return &Host{ Name: params.Name, diff --git a/routers/api/v2/hosts.go b/routers/api/v2/hosts.go index 838918fd..850c328b 100644 --- a/routers/api/v2/hosts.go +++ b/routers/api/v2/hosts.go @@ -24,11 +24,45 @@ func ListHosts(c *gin.Context) { if err != nil { context.ServerError(err, fmt.Errorf("failed to get host info")) } - dtoHosts := make([]body.HostRead, 0) for _, host := range hostInfo { dtoHosts = append(dtoHosts, host.ToDTO()) } + context.JSONResponse(200, dtoHosts) +} + +// VerboseListHosts +// @Summary List Hosts verbose +// @Description List Hosts verbose +// @Tags Host +// @Produce json +// @Security ApiKeyAuth +// @Security KeycloakOAuth +// @Success 200 {array} body.HostVerboseRead +// @Failure 403 {object} sys.ErrorResponse +// @Failure 500 {object} sys.ErrorResponse +// @Router /v2/hosts/verbose [get] +func VerboseListHosts(c *gin.Context) { + context := sys.NewContext(c) + auth, err := WithAuth(&context) + if err != nil { + context.ServerError(err, ErrAuthInfoNotAvailable) + return + } + + if (auth != nil && !auth.User.IsAdmin) || auth == nil { + context.Forbidden("Not permitted to request verbose host information") + return + } + + hostInfo, err := service.V2().System().ListHosts() + if err != nil { + context.ServerError(err, fmt.Errorf("failed to get host info")) + } + dtoHosts := make([]body.HostVerboseRead, 0) + for _, host := range hostInfo { + dtoHosts = append(dtoHosts, host.ToVerboseDTO()) + } context.JSONResponse(200, dtoHosts) } diff --git a/routers/routes/host.go b/routers/routes/host.go index 1809642a..7442ba02 100644 --- a/routers/routes/host.go +++ b/routers/routes/host.go @@ -3,8 +3,9 @@ package routes import v2 "github.com/kthcloud/go-deploy/routers/api/v2" const ( - HostsPath = "/v2/hosts" - HostPath = "/v2/hosts/:hostId" + HostsPath = "/v2/hosts" + HostsPathVerbose = "/v2/hosts/verbose" + HostPath = "/v2/hosts/:hostId" ) type HostRoutingGroup struct{ RoutingGroupBase } @@ -18,3 +19,9 @@ func (group *HostRoutingGroup) PublicRoutes() []Route { {Method: "GET", Pattern: HostsPath, HandlerFunc: v2.ListHosts}, } } + +func (group *HostRoutingGroup) PrivateRoutes() []Route { + return []Route{ + {Method: "GET", Pattern: HostsPathVerbose, HandlerFunc: v2.VerboseListHosts}, + } +} From e5e28db58b78c12bbf1468b05e78ed87ca21a5c7 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Fri, 24 Jan 2025 00:39:44 +0100 Subject: [PATCH 25/36] rm temp test file --- test/temp_test.go | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 test/temp_test.go diff --git a/test/temp_test.go b/test/temp_test.go deleted file mode 100644 index 34f9cd03..00000000 --- a/test/temp_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package test - -import ( - "errors" - "testing" - - er "github.com/kthcloud/go-deploy/pkg/services/errors" -) - -func TestList(t *testing.T) { - if errors.Is(er.NewHostsFailedErr([]string{"t01n14", "t01n16"}), er.ErrNoHosts) { - t.Fail() - } -} From 8cd4bffa3012660986d3fe66aa9ec38c93561e7d Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Thu, 30 Jan 2025 19:52:27 +0100 Subject: [PATCH 26/36] include lastSeenAt in verboseHost DTO --- models/model/host.go | 1 + routers/api/v2/hosts.go | 2 +- service/v2/api/api_client.go | 4 +++- service/v2/system/host_service.go | 10 ++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/models/model/host.go b/models/model/host.go index 575d865c..d4a06628 100644 --- a/models/model/host.go +++ b/models/model/host.go @@ -51,6 +51,7 @@ func (host *Host) ToVerboseDTO() body.HostVerboseRead { Enabled: host.Enabled, Schedulable: host.Schedulable, DeactivatedUntil: host.DeactivatedUntil, + LastSeenAt: host.LastSeenAt, RegisteredAt: host.RegisteredAt, } } diff --git a/routers/api/v2/hosts.go b/routers/api/v2/hosts.go index 850c328b..97b38a1d 100644 --- a/routers/api/v2/hosts.go +++ b/routers/api/v2/hosts.go @@ -56,7 +56,7 @@ func VerboseListHosts(c *gin.Context) { return } - hostInfo, err := service.V2().System().ListHosts() + hostInfo, err := service.V2().System().ListAllHosts() if err != nil { context.ServerError(err, fmt.Errorf("failed to get host info")) } diff --git a/service/v2/api/api_client.go b/service/v2/api/api_client.go index f3ee9d94..cae6f12a 100644 --- a/service/v2/api/api_client.go +++ b/service/v2/api/api_client.go @@ -2,6 +2,8 @@ package api import ( "context" + "time" + "github.com/kthcloud/go-deploy/dto/v2/body" configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" @@ -18,7 +20,6 @@ import ( userOpts "github.com/kthcloud/go-deploy/service/v2/users/opts" vmK8sService "github.com/kthcloud/go-deploy/service/v2/vms/k8s_service" vmOpts "github.com/kthcloud/go-deploy/service/v2/vms/opts" - "time" ) type Deployments interface { @@ -195,6 +196,7 @@ type System interface { RegisterNode(params *body.HostRegisterParams) error ListHosts() ([]model.Host, error) + ListAllHosts() ([]model.Host, error) GetZone(name string) *configModels.Zone ListZones(opts ...systemOpts.ListOpts) ([]configModels.Zone, error) diff --git a/service/v2/system/host_service.go b/service/v2/system/host_service.go index f6079b6c..36b4780d 100644 --- a/service/v2/system/host_service.go +++ b/service/v2/system/host_service.go @@ -14,3 +14,13 @@ func (c *Client) ListHosts() ([]model.Host, error) { return hosts, nil } + +// ListAllHosts gets a list of all hosts +func (c *Client) ListAllHosts() ([]model.Host, error) { + hosts, err := host_repo.New().List() + if err != nil { + return nil, err + } + + return hosts, nil +} From b860b5833cc8504f6ec0ecc9bd736a15b724a0b0 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 01:23:24 +0200 Subject: [PATCH 27/36] add support for exposing multiple internal ports --- Dockerfile | 2 +- cached.Dockerfile | 2 +- models/model/deployment_convert.go | 36 +++++ models/model/deployment_params.go | 40 +++--- models/model/deployment_related.go | 11 +- scripts/check-lint.sh | 131 +++++++++++------- .../v2/deployments/resources/k8s_generator.go | 39 +++++- 7 files changed, 184 insertions(+), 77 deletions(-) diff --git a/Dockerfile b/Dockerfile index 36f9abd3..f28afc35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ RUN go mod download # Copy the rest of the project to ensure code changes doesnt trigger re-download of all deps COPY . . -RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$GOARCH go build -a -installsuffix cgo -o main . +RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -a -installsuffix cgo -o main . ############################ diff --git a/cached.Dockerfile b/cached.Dockerfile index 9c9f30d1..5be85313 100644 --- a/cached.Dockerfile +++ b/cached.Dockerfile @@ -23,7 +23,7 @@ COPY . . ENV GOCACHE=/root/.cache/go-build RUN --mount=type=cache,target=/go/pkg/mod/ \ --mount=type=cache,target="/root/.cache/go-build" \ - CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$GOARCH go build -a -installsuffix cgo -o main . + CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -a -installsuffix cgo -o main . ############################ diff --git a/models/model/deployment_convert.go b/models/model/deployment_convert.go index b7290195..2df1ab86 100644 --- a/models/model/deployment_convert.go +++ b/models/model/deployment_convert.go @@ -3,6 +3,7 @@ package model import ( "fmt" "strconv" + "strings" "github.com/kthcloud/go-deploy/dto/v2/body" "github.com/kthcloud/go-deploy/pkg/log" @@ -25,6 +26,16 @@ func (deployment *Deployment) ToDTO(smURL *string, externalPort *int, teams []st Value: fmt.Sprintf("%d", app.InternalPort), }) + portsStr := make([]string, len(app.InternallPorts)) + for i, port := range app.InternallPorts { + portsStr[i] = strconv.Itoa(port) + } + + envs = append(envs, body.Env{ + Name: "INTERNAL_PORTS", + Value: strings.Join(portsStr, ","), + }) + for i, env := range app.Envs { envs[i] = body.Env{ Name: env.Name, @@ -171,6 +182,18 @@ func (p *DeploymentCreateParams) FromDTO(dto *body.DeploymentCreate, fallbackZon p.InternalPort = port continue } + if env.Name == "INTERNAL_PORTS" { + portsStr := strings.Split(env.Value, ",") + var internalPorts []int + for _, prt := range portsStr { + prt = strings.TrimSpace(prt) + if port, err := strconv.Atoi(prt); err == nil { + internalPorts = append(internalPorts, port) + } + } + p.InternalPorts = internalPorts + continue + } p.Envs = append(p.Envs, DeploymentEnv{ Name: env.Name, @@ -240,6 +263,19 @@ func (p *DeploymentUpdateParams) FromDTO(dto *body.DeploymentUpdate, deploymentT continue } + if env.Name == "INTERNAL_PORTS" { + portsStr := strings.Split(env.Value, ",") + var internalPorts []int + for _, prt := range portsStr { + prt = strings.TrimSpace(prt) + if port, err := strconv.Atoi(prt); err == nil { + internalPorts = append(internalPorts, port) + } + } + p.InternalPorts = &internalPorts + continue + } + envs = append(envs, DeploymentEnv{ Name: env.Name, Value: env.Value, diff --git a/models/model/deployment_params.go b/models/model/deployment_params.go index d94dc569..7edaa145 100644 --- a/models/model/deployment_params.go +++ b/models/model/deployment_params.go @@ -8,15 +8,16 @@ type DeploymentCreateParams struct { RAM float64 Replicas int - Image string - InternalPort int - Envs []DeploymentEnv - Volumes []DeploymentVolume - InitCommands []string - Args []string - PingPath string - CustomDomain *string - Visibility string + Image string + InternalPort int + InternalPorts []int + Envs []DeploymentEnv + Volumes []DeploymentVolume + InitCommands []string + Args []string + PingPath string + CustomDomain *string + Visibility string NeverStale bool @@ -30,16 +31,17 @@ type DeploymentUpdateParams struct { CpuCores *float64 RAM *float64 - Envs *[]DeploymentEnv - InternalPort *int - Volumes *[]DeploymentVolume - InitCommands *[]string - Args *[]string - CustomDomain *string - Image *string - PingPath *string - Replicas *int - Visibility *string + Envs *[]DeploymentEnv + InternalPort *int + InternalPorts *[]int + Volumes *[]DeploymentVolume + InitCommands *[]string + Args *[]string + CustomDomain *string + Image *string + PingPath *string + Replicas *int + Visibility *string NeverStale *bool } diff --git a/models/model/deployment_related.go b/models/model/deployment_related.go index 4d20749c..5f4d5845 100644 --- a/models/model/deployment_related.go +++ b/models/model/deployment_related.go @@ -36,11 +36,12 @@ type App struct { RAM float64 `bson:"ram,omitempty"` Replicas int `bson:"replicas"` - Image string `bson:"image"` - InternalPort int `bson:"internalPort"` - Envs []DeploymentEnv `bson:"envs"` - Volumes []DeploymentVolume `bson:"volumes"` - Visibility string `bson:"visibility"` + Image string `bson:"image"` + InternalPort int `bson:"internalPort"` + InternallPorts []int `bson:"internallPorts"` + Envs []DeploymentEnv `bson:"envs"` + Volumes []DeploymentVolume `bson:"volumes"` + Visibility string `bson:"visibility"` // Deprecated: use Visibility instead. Private bool `bson:"private"` diff --git a/scripts/check-lint.sh b/scripts/check-lint.sh index 1caa646f..4f6fd408 100755 --- a/scripts/check-lint.sh +++ b/scripts/check-lint.sh @@ -1,104 +1,133 @@ -#!/bin/sh +#!/usr/bin/env bash + +RED="\e[31m" +YELLOW="\e[33m" +GREEN="\e[32m" +BLUE="\e[34m" +GRAY="\e[90m" +RESET="\e[0m" + +ERROR_LOG="${RED}[ERROR]${RESET}" +WARN_LOG="${YELLOW}[WARN]${RESET}" +INFO_LOG="${GREEN}[INFO]${RESET}" +PRINT_INDENT_LOG="${GRAY}||===>${RESET}" + +log_err() { + echo -e "$ERROR_LOG $1" >&2 +} + +log_warn() { + echo -e "$WARN_LOG $1" >&2 +} + +log_info() { + echo -e "$INFO_LOG $1" >&2 +} -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -NC='\033[0m' # No Color +log_print() { + echo -e "$PRINT_INDENT_LOG $1" >&2 +} -function get_git_root() { - git rev-parse --show-toplevel 2>/dev/null || { echo -e "${RED}This is not a git repository. Please run this script from within the Git repository.${NC}"; exit 1; } +get_git_root() { + git rev-parse --show-toplevel 2>/dev/null || { echo -e "${RED}This is not a git repository. Please run this script from within the Git repository.${RESET}"; exit 1; } } -function check_gofmt() { - command -v gofmt >/dev/null 2>&1 || { echo -e "${RED}gofmt is not installed. Please install it to continue.${NC}"; exit 1; } +check_gofmt() { + command -v gofmt >/dev/null 2>&1 || { echo -e "${RED}gofmt is not installed. Please install it to continue.${RESET}"; exit 1; } } -function check_go_vet() { - command -v go >/dev/null 2>&1 || { echo -e "${RED}go is not installed. Please install Go to continue.${NC}"; exit 1; } +check_go_vet() { + command -v go >/dev/null 2>&1 || { echo -e "${RED}go is not installed. Please install Go to continue.${RESET}"; exit 1; } } -function check_go_cyclo() { - command -v gocyclo >/dev/null 2>&1 || { echo -e "${YELLOW}go-cyclo is not installed. Installing...${NC}"; go install github.com/fzipp/gocyclo/cmd/gocyclo@latest; } +check_go_cyclo() { + command -v gocyclo >/dev/null 2>&1 || { echo -e "${YELLOW}go-cyclo is not installed. Installing...${RESET}"; go install github.com/fzipp/gocyclo/cmd/gocyclo@latest; } } -function check_ineffassign() { - command -v ineffassign >/dev/null 2>&1 || { echo -e "${YELLOW}ineffassign is not installed. Installing...${NC}"; go install github.com/gordonklaus/ineffassign@latest; } +check_ineffassign() { + command -v ineffassign >/dev/null 2>&1 || { echo -e "${YELLOW}ineffassign is not installed. Installing...${RESET}"; go install github.com/gordonklaus/ineffassign@latest; } } -function check_staticcheck() { - command -v staticcheck >/dev/null 2>&1 || { echo -e "${YELLOW}go-staticcheck is not installed. Installing...${NC}"; go install honnef.co/go/tools/cmd/staticcheck@latest; } +check_staticcheck() { + command -v staticcheck >/dev/null 2>&1 || { echo -e "${YELLOW}go-staticcheck is not installed. Installing...${RESET}"; go install honnef.co/go/tools/cmd/staticcheck@latest; } } -function run_gofmt() { - echo -e "${YELLOW}Running gofmt check...${NC}" +run_gofmt() { + log_info "${YELLOW}Running gofmt check...${RESET}" # Check for formatting issues gofmt_output=$(gofmt -l .) if [ -n "$gofmt_output" ]; then - echo -e "${RED}gofmt found the following issues:${NC}" - echo "$gofmt_output" + log_err "${RED}gofmt found the following issues:${RESET}" + echo "$gofmt_output" | while IFS= read -r line; do + log_print "\t$line" + done gofmt_error=1 else - echo -e "${GREEN}passed gofmt.${NC}" + log_print "${GREEN}passed gofmt.${RESET}" fi } -function run_go_vet() { - echo -e "${YELLOW}Running go vet check...${NC}" +run_go_vet() { + log_info "${YELLOW}Running go vet check...${RESET}" # Run go vet to analyze code for potential issues go_vet_output=$(go vet ./... 2>&1) if [ -n "$go_vet_output" ]; then - echo -e "${RED}go vet found the following issues:${NC}" - echo "$go_vet_output" + log_err "${RED}go vet found the following issues:${RESET}" + echo "$go_vet_output" | while IFS= read -r line; do + log_print "\t$line" + done go_vet_error=1 else - echo -e "${GREEN}passed go vet.${NC}" + log_print "${GREEN}passed go vet.${RESET}" fi } -function run_go_cyclo() { - echo -e "${YELLOW}Running go-cyclo check...${NC}" +run_go_cyclo() { + log_info "${YELLOW}Running go-cyclo check...${RESET}" # Check for cyclomatic complexity go_cyclo_output=$(find . -path ./pkg/imp -prune -o -type f -name "*.go" -exec gocyclo -over 15 {} +) if [ -n "$go_cyclo_output" ]; then - echo -e "${RED}gocyclo found the following issues:${NC}" - echo "$go_cyclo_output" + log_err "${RED}gocyclo found the following issues:${RESET}" + echo "$go_cyclo_output" | while IFS= read -r line; do + log_print "\t$line" + done go_cyclo_error=1 else - echo -e "${GREEN}passed gocyclo -over 15.${NC}" + log_print "${GREEN}passed gocyclo -over 15.${RESET}" fi } -function run_ineffassign() { - echo -e "${YELLOW}Running ineffassign check...${NC}" +run_ineffassign() { + log_info "${YELLOW}Running ineffassign check...${RESET}" # Check for unused variable assignments ineffassign_output=$(ineffassign .) if [ -n "$ineffassign_output" ]; then - echo -e "${RED}ineffassign found the following issues:${NC}" - echo "$ineffassign_output" + log_err "${RED}ineffassign found the following issues:${RESET}" + echo "$ineffassign_output" | while IFS= read -r line; do + log_print "\t$line" + done ineffassign_error=1 else - echo -e "${GREEN}passed ineffassign.${NC}" + log_print "${GREEN}passed ineffassign.${RESET}" fi } -function run_staticcheck() { - echo -e "${YELLOW}Running go-staticcheck check...${NC}" +run_staticcheck() { + log_info "${YELLOW}Running go-staticcheck check...${RESET}" # Run staticcheck to analyze code for potential issues staticcheck_output=$(staticcheck ./...) if [ -n "$staticcheck_output" ]; then - echo -e "${RED}go-staticcheck found the following issues:${NC}" - echo "$staticcheck_output" + log_err "${RED}go-staticcheck found the following issues:${RESET}" + echo "$staticcheck_output" | while IFS= read -r line; do + log_print "\t$line" + done staticcheck_error=1 else - echo -e "${GREEN}passed go-staticcheck.${NC}" + log_print "${GREEN}passed go-staticcheck.${RESET}" fi } -# Get the git root, to make sure the scripts are run in the correct location -git_root=$(get_git_root) - -# Change to the Git root directory -cd "$git_root" || { echo -e "${RED}Failed to change to the Git root directory.${NC}"; exit 1; } +pushd "$(dirname "${BASH_SOURCE[0]}")/.." > /dev/null || { log_err "Failed to change to script directory."; exit 1; } # Ensure all tools are installed check_gofmt @@ -107,6 +136,8 @@ check_go_cyclo check_ineffassign check_staticcheck +go mod download + # Initialize error flags gofmt_error=0 go_vet_error=0 @@ -123,9 +154,11 @@ run_staticcheck # Print a summary and exit with failure if there were any errors if [ $gofmt_error -eq 1 ] || [ $go_vet_error -eq 1 ] || [ $go_cyclo_error -eq 1 ] || [ $ineffassign_error -eq 1 ] || [ $staticcheck_error -eq 1 ]; then - echo -e "${RED}SUMMARY: Please resolve the above issues.${NC}" + echo -e "${RED}SUMMARY: Please resolve the above issues.${RESET}" + popd > /dev/null exit 1 else - echo -e "${GREEN}All checks passed successfully.${NC}" + echo -e "${GREEN}All checks passed successfully.${RESET}" + popd > /dev/null exit 0 fi diff --git a/service/v2/deployments/resources/k8s_generator.go b/service/v2/deployments/resources/k8s_generator.go index 6505d61d..5d46ddd1 100644 --- a/service/v2/deployments/resources/k8s_generator.go +++ b/service/v2/deployments/resources/k8s_generator.go @@ -8,6 +8,7 @@ import ( "path" "regexp" "slices" + "strconv" "strings" "time" @@ -67,7 +68,7 @@ func (kg *K8sGenerator) Deployments() []models.DeploymentPublic { k8sEnvs := make([]models.EnvVar, len(mainApp.Envs)) for i, env := range mainApp.Envs { - if env.Name == "PORT" { + if env.Name == "PORT" || env.Name == "INTERNAL_PORTS" { continue } @@ -82,6 +83,16 @@ func (kg *K8sGenerator) Deployments() []models.DeploymentPublic { Value: fmt.Sprintf("%d", mainApp.InternalPort), }) + portsStr := make([]string, len(mainApp.InternallPorts)) + for i, port := range mainApp.InternallPorts { + portsStr[i] = strconv.Itoa(port) + } + + k8sEnvs = append(k8sEnvs, models.EnvVar{ + Name: "INTERNAL_PORTS", + Value: strings.Join(portsStr, ","), + }) + k8sVolumes := make([]models.Volume, len(mainApp.Volumes)) for i, volume := range mainApp.Volumes { pvcName := fmt.Sprintf("%s-%s", kg.deployment.Name, makeValidK8sName(volume.Name)) @@ -257,10 +268,34 @@ func (kg *K8sGenerator) Services() []models.ServicePublic { res := make([]models.ServicePublic, 0) + // Add the base http port + ports := []models.Port{ + { + Name: "http", + Protocol: "tcp", + Port: mainApp.InternalPort, + TargetPort: mainApp.InternalPort, + }, + } + + // add all internalPorts to expose to the with the service + for _, p := range mainApp.InternallPorts { + if p == mainApp.InternalPort { + continue + } + + ports = append(ports, models.Port{ + Name: fmt.Sprintf("port-%d", p), + Protocol: "tcp", + Port: p, + TargetPort: p, + }) + } + se := models.ServicePublic{ Name: kg.deployment.Name, Namespace: kg.namespace, - Ports: []models.Port{{Name: "http", Protocol: "tcp", Port: mainApp.InternalPort, TargetPort: mainApp.InternalPort}}, + Ports: ports, Selector: map[string]string{ keys.LabelDeployName: kg.deployment.Name, }, From f2eaf83735c857c10412cbcd7e65b4a09ae4e170 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 02:21:01 +0200 Subject: [PATCH 28/36] fix persist in db + spellfix --- dto/v2/body/deployment.go | 1 + models/model/deployment_convert.go | 5 +++-- models/model/deployment_related.go | 12 ++++++------ pkg/db/resources/deployment_repo/db.go | 11 ++++++----- service/v2/deployments/resources/k8s_generator.go | 8 ++++---- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/dto/v2/body/deployment.go b/dto/v2/body/deployment.go index b770676b..2b3367ac 100644 --- a/dto/v2/body/deployment.go +++ b/dto/v2/body/deployment.go @@ -25,6 +25,7 @@ type DeploymentRead struct { InitCommands []string `json:"initCommands"` Args []string `json:"args"` InternalPort int `json:"internalPort"` + InternalPorts []int `json:"internalPorts"` Image *string `json:"image,omitempty"` HealthCheckPath *string `json:"healthCheckPath,omitempty"` CustomDomain *CustomDomainRead `json:"customDomain,omitempty"` diff --git a/models/model/deployment_convert.go b/models/model/deployment_convert.go index 2df1ab86..4b128975 100644 --- a/models/model/deployment_convert.go +++ b/models/model/deployment_convert.go @@ -26,8 +26,8 @@ func (deployment *Deployment) ToDTO(smURL *string, externalPort *int, teams []st Value: fmt.Sprintf("%d", app.InternalPort), }) - portsStr := make([]string, len(app.InternallPorts)) - for i, port := range app.InternallPorts { + portsStr := make([]string, len(app.InternalPorts)) + for i, port := range app.InternalPorts { portsStr[i] = strconv.Itoa(port) } @@ -136,6 +136,7 @@ func (deployment *Deployment) ToDTO(smURL *string, externalPort *int, teams []st InitCommands: app.InitCommands, Args: app.Args, InternalPort: app.InternalPort, + InternalPorts: app.InternalPorts, Image: image, HealthCheckPath: healthCheckPath, CustomDomain: customDomain, diff --git a/models/model/deployment_related.go b/models/model/deployment_related.go index 5f4d5845..f71ef34e 100644 --- a/models/model/deployment_related.go +++ b/models/model/deployment_related.go @@ -36,12 +36,12 @@ type App struct { RAM float64 `bson:"ram,omitempty"` Replicas int `bson:"replicas"` - Image string `bson:"image"` - InternalPort int `bson:"internalPort"` - InternallPorts []int `bson:"internallPorts"` - Envs []DeploymentEnv `bson:"envs"` - Volumes []DeploymentVolume `bson:"volumes"` - Visibility string `bson:"visibility"` + Image string `bson:"image"` + InternalPort int `bson:"internalPort"` + InternalPorts []int `bson:"internallPorts"` + Envs []DeploymentEnv `bson:"envs"` + Volumes []DeploymentVolume `bson:"volumes"` + Visibility string `bson:"visibility"` // Deprecated: use Visibility instead. Private bool `bson:"private"` diff --git a/pkg/db/resources/deployment_repo/db.go b/pkg/db/resources/deployment_repo/db.go index a34b50bc..7059faa8 100644 --- a/pkg/db/resources/deployment_repo/db.go +++ b/pkg/db/resources/deployment_repo/db.go @@ -40,11 +40,12 @@ func (client *Client) Create(id, ownerID string, params *model.DeploymentCreateP RAM: params.RAM, Replicas: params.Replicas, - Image: params.Image, - InternalPort: params.InternalPort, - Envs: params.Envs, - Volumes: params.Volumes, - Visibility: params.Visibility, + Image: params.Image, + InternalPort: params.InternalPort, + InternalPorts: params.InternalPorts, + Envs: params.Envs, + Volumes: params.Volumes, + Visibility: params.Visibility, Args: params.Args, InitCommands: params.InitCommands, diff --git a/service/v2/deployments/resources/k8s_generator.go b/service/v2/deployments/resources/k8s_generator.go index 5d46ddd1..8e85c3bc 100644 --- a/service/v2/deployments/resources/k8s_generator.go +++ b/service/v2/deployments/resources/k8s_generator.go @@ -83,8 +83,8 @@ func (kg *K8sGenerator) Deployments() []models.DeploymentPublic { Value: fmt.Sprintf("%d", mainApp.InternalPort), }) - portsStr := make([]string, len(mainApp.InternallPorts)) - for i, port := range mainApp.InternallPorts { + portsStr := make([]string, len(mainApp.InternalPorts)) + for i, port := range mainApp.InternalPorts { portsStr[i] = strconv.Itoa(port) } @@ -279,8 +279,8 @@ func (kg *K8sGenerator) Services() []models.ServicePublic { } // add all internalPorts to expose to the with the service - for _, p := range mainApp.InternallPorts { - if p == mainApp.InternalPort { + for _, p := range mainApp.InternalPorts { + if p == mainApp.InternalPort || p == 0 { continue } From 6dd7e44a9efd99b2709b7372d5f3aecf6ce4792d Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 02:51:17 +0200 Subject: [PATCH 29/36] fix persist on update --- docs/api/v2/V2_docs.go | 2 +- docs/api/v2/V2_swagger.json | 2 +- docs/api/v2/V2_swagger.yaml | 5 +++++ export/types/v2/body/index.ts | 1 + pkg/db/resources/deployment_repo/db.go | 1 + 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/api/v2/V2_docs.go b/docs/api/v2/V2_docs.go index 6e86409f..b06eb519 100644 --- a/docs/api/v2/V2_docs.go +++ b/docs/api/v2/V2_docs.go @@ -6,7 +6,7 @@ import "github.com/swaggo/swag/v2" const docTemplateV2 = `{ "schemes": {{ marshal .Schemes }}, - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"internalPorts":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"{{escape .Description}}","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"{{.Title}}","version":"{{.Version}}"}, "externalDocs": {"description":"","url":""}, "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/hosts/verbose":{"get":{"description":"List Hosts verbose","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostVerboseRead"},"type":"array"}}},"description":"OK"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List Hosts verbose","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, diff --git a/docs/api/v2/V2_swagger.json b/docs/api/v2/V2_swagger.json index bd5358b1..d9eef331 100644 --- a/docs/api/v2/V2_swagger.json +++ b/docs/api/v2/V2_swagger.json @@ -1,5 +1,5 @@ { - "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, + "components": {"schemas":{"body.ApiKey":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.ApiKeyCreate":{"properties":{"expiresAt":{"type":"string"},"name":{"type":"string"}},"required":["expiresAt","name"],"type":"object"},"body.ApiKeyCreated":{"properties":{"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}},"type":"object"},"body.BindingError":{"properties":{"validationErrors":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"}},"type":"object"},"body.CiConfig":{"properties":{"config":{"type":"string"}},"type":"object"},"body.ClusterCapacities":{"properties":{"cluster":{"type":"string"},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.ClusterStats":{"properties":{"cluster":{"type":"string"},"podCount":{"type":"integer"}},"type":"object"},"body.CpuCoreCapacities":{"description":"Total","properties":{"total":{"type":"integer"}},"type":"object"},"body.CpuStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.CpuStatusLoad"},"temp":{"$ref":"#/components/schemas/body.CpuStatusTemp"}},"type":"object"},"body.CpuStatusLoad":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CpuStatusTemp":{"properties":{"cores":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"main":{"type":"number"},"max":{"type":"number"}},"type":"object"},"body.CustomDomainRead":{"properties":{"domain":{"type":"string"},"secret":{"type":"string"},"status":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.DeploymentCommand":{"properties":{"command":{"enum":["restart"],"type":"string"}},"required":["command"],"type":"object"},"body.DeploymentCreate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"description":"Boolean to make deployment never get disabled, despite being stale","type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"zone":{"description":"Zone is the zone that the deployment will be created in.\nIf the zone is not set, the deployment will be created in the default zone.","type":"string"}},"required":["name"],"type":"object"},"body.DeploymentCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DeploymentRead":{"properties":{"accessedAt":{"type":"string"},"args":{"items":{"type":"string"},"type":"array","uniqueItems":false},"createdAt":{"type":"string"},"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"type":"array","uniqueItems":false},"error":{"type":"string"},"healthCheckPath":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"initCommands":{"items":{"type":"string"},"type":"array","uniqueItems":false},"integrations":{"description":"Integrations are currently not used, but could be used if we wanted to add a list of integrations to the deployment\n\nFor example GitHub","items":{"type":"string"},"type":"array","uniqueItems":false},"internalPort":{"type":"integer"},"internalPorts":{"items":{"type":"integer"},"type":"array","uniqueItems":false},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"pingResult":{"type":"integer"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"repairedAt":{"type":"string"},"replicaStatus":{"$ref":"#/components/schemas/body.ReplicaStatus"},"restartedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.DeploymentSpecs"},"status":{"type":"string"},"storageUrl":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"type":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"},"visibility":{"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"type":"array","uniqueItems":false},"zone":{"type":"string"}},"type":"object"},"body.DeploymentSpecs":{"properties":{"cpuCores":{"type":"number"},"ram":{"type":"number"},"replicas":{"type":"integer"}},"type":"object"},"body.DeploymentUpdate":{"properties":{"args":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"cpuCores":{"type":"number"},"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"envs":{"items":{"$ref":"#/components/schemas/body.Env"},"maxItems":1000,"minItems":0,"type":"array","uniqueItems":false},"healthCheckPath":{"maxLength":1000,"minLength":0,"type":"string"},"image":{"maxLength":1000,"minLength":1,"type":"string"},"initCommands":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"private":{"description":"Deprecated: Use Visibility instead.","type":"boolean"},"ram":{"type":"number"},"replicas":{"maximum":100,"minimum":0,"type":"integer"},"visibility":{"enum":["public","private","auth"],"type":"string"},"volumes":{"items":{"$ref":"#/components/schemas/body.Volume"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.DeploymentUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.DiscoverRead":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/body.Role"},"type":"array","uniqueItems":false},"version":{"type":"string"}},"type":"object"},"body.Env":{"properties":{"name":{"maxLength":100,"minLength":1,"type":"string"},"value":{"maxLength":10000,"minLength":1,"type":"string"}},"required":["name","value"],"type":"object"},"body.GpuCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.GpuGroupRead":{"properties":{"available":{"type":"integer"},"displayName":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"total":{"type":"integer"},"vendor":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.GpuLeaseCreate":{"properties":{"gpuGroupId":{"description":"GpuGroupID is used to specify the GPU to lease.\nAs such, the lease does not specify which specific GPU to lease, but rather the type of GPU to lease.","type":"string"},"leaseForever":{"description":"LeaseForever is used to specify whether the lease should be created forever.","type":"boolean"}},"required":["gpuGroupId"],"type":"object"},"body.GpuLeaseCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuLeaseRead":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"active":{"type":"boolean"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"},"queuePosition":{"type":"integer"},"userId":{"type":"string"},"vmId":{"description":"VmID is set when the lease is attached to a VM.","type":"string"}},"type":"object"},"body.GpuLeaseUpdate":{"properties":{"vmId":{"description":"VmID is used to specify the VM to attach the lease to.\n\n- If specified, the lease will be attached to the VM.\n\n- If the lease is already attached to a VM, it will be detached from the current VM and attached to the new VM.\n\n- If the lease is not active, specifying a VM will activate the lease.\n\n- If the lease is not assigned, an error will be returned.","type":"string"}},"type":"object"},"body.GpuLeaseUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.GpuStatus":{"properties":{"temp":{"items":{"$ref":"#/components/schemas/body.GpuStatusTemp"},"type":"array","uniqueItems":false}},"type":"object"},"body.GpuStatusTemp":{"properties":{"main":{"type":"number"}},"type":"object"},"body.HarborWebhook":{"properties":{"event_data":{"properties":{"repository":{"properties":{"date_created":{"type":"integer"},"name":{"type":"string"},"namespace":{"type":"string"},"repo_full_name":{"type":"string"},"repo_type":{"type":"string"}},"type":"object"},"resources":{"items":{"properties":{"digest":{"type":"string"},"resource_url":{"type":"string"},"tag":{"type":"string"}},"type":"object"},"type":"array","uniqueItems":false}},"type":"object"},"occur_at":{"type":"integer"},"operator":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.HostCapacities":{"properties":{"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamCapacities"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostRead":{"properties":{"displayName":{"type":"string"},"name":{"type":"string"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostStatus":{"properties":{"cpu":{"$ref":"#/components/schemas/body.CpuStatus"},"displayName":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.GpuStatus"},"name":{"type":"string"},"ram":{"$ref":"#/components/schemas/body.RamStatus"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HostVerboseRead":{"properties":{"deactivatedUntil":{"type":"string"},"displayName":{"type":"string"},"enabled":{"type":"boolean"},"ip":{"type":"string"},"lastSeenAt":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"registeredAt":{"type":"string"},"schedulable":{"type":"boolean"},"zone":{"description":"Zone is the name of the zone where the host is located.","type":"string"}},"type":"object"},"body.HttpProxyCreate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.HttpProxyRead":{"properties":{"customDomain":{"$ref":"#/components/schemas/body.CustomDomainRead"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"body.HttpProxyUpdate":{"properties":{"customDomain":{"description":"CustomDomain is the domain that the deployment will be available on.\nThe max length is set to 243 to allow for a subdomain when confirming the domain.","type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"}},"required":["name"],"type":"object"},"body.JobRead":{"properties":{"createdAt":{"type":"string"},"finishedAt":{"type":"string"},"id":{"type":"string"},"lastError":{"type":"string"},"lastRunAt":{"type":"string"},"runAfter":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.JobUpdate":{"properties":{"status":{"enum":["pending","running","failed","terminated","finished","completed"],"type":"string"}},"type":"object"},"body.K8sStats":{"properties":{"clusters":{"items":{"$ref":"#/components/schemas/body.ClusterStats"},"type":"array","uniqueItems":false},"podCount":{"type":"integer"}},"type":"object"},"body.NotificationRead":{"properties":{"completedAt":{"type":"string"},"content":{"additionalProperties":{},"type":"object"},"createdAt":{"type":"string"},"id":{"type":"string"},"readAt":{"type":"string"},"toastedAt":{"type":"string"},"type":{"type":"string"},"userId":{"type":"string"}},"type":"object"},"body.NotificationUpdate":{"properties":{"read":{"type":"boolean"},"toasted":{"type":"boolean"}},"type":"object"},"body.PortCreate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyCreate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PortRead":{"properties":{"externalPort":{"type":"integer"},"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyRead"},"name":{"type":"string"},"port":{"type":"integer"},"protocol":{"type":"string"}},"type":"object"},"body.PortUpdate":{"properties":{"httpProxy":{"$ref":"#/components/schemas/body.HttpProxyUpdate"},"name":{"maxLength":100,"minLength":1,"type":"string"},"port":{"maximum":65535,"minimum":1,"type":"integer"},"protocol":{"enum":["tcp","udp"],"type":"string"}},"required":["name","port","protocol"],"type":"object"},"body.PublicKey":{"properties":{"key":{"type":"string"},"name":{"maxLength":30,"minLength":1,"type":"string"}},"required":["key","name"],"type":"object"},"body.Quota":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"number"},"gpuLeaseDuration":{"description":"in hours","type":"number"},"ram":{"type":"number"},"snapshots":{"type":"integer"}},"type":"object"},"body.RamCapacities":{"properties":{"total":{"type":"integer"}},"type":"object"},"body.RamStatus":{"properties":{"load":{"$ref":"#/components/schemas/body.RamStatusLoad"}},"type":"object"},"body.RamStatusLoad":{"properties":{"main":{"type":"number"}},"type":"object"},"body.ReplicaStatus":{"properties":{"availableReplicas":{"description":"AvailableReplicas is the number of replicas that are available.","type":"integer"},"desiredReplicas":{"description":"DesiredReplicas is the number of replicas that the deployment should have.","type":"integer"},"readyReplicas":{"description":"ReadyReplicas is the number of replicas that are ready.","type":"integer"},"unavailableReplicas":{"description":"UnavailableReplicas is the number of replicas that are unavailable.","type":"integer"}},"type":"object"},"body.ResourceMigrationCreate":{"properties":{"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used by privileged admins to directly accept or reject a migration.\nThe field is ignored by non-admins.\n\nPossible values:\n- accepted\n- pending","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","enum":["updateOwner"],"type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is ignored if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"required":["ownerId"],"type":"object"}},"required":["resourceId","type"],"type":"object"},"body.ResourceMigrationCreated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was created with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationRead":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.ResourceMigrationUpdate":{"properties":{"code":{"description":"Code is a token required when accepting a migration if the acceptor is not an admin.\nIt is sent to the acceptor using the notification API","type":"string"},"status":{"description":"Status is the status of the resource migration.\nIt is used to accept a migration by setting the status to 'accepted'.\nIf the acceptor is not an admin, a Code must be provided.\n\nPossible values:\n- accepted\n- pending","type":"string"}},"required":["status"],"type":"object"},"body.ResourceMigrationUpdated":{"properties":{"createdAt":{"type":"string"},"deletedAt":{"type":"string"},"id":{"type":"string"},"jobId":{"description":"JobID is the ID of the job that was created for the resource migration.\nIt will only be set if the migration was updated with status 'accepted'.","type":"string"},"resourceId":{"description":"ResourceID is the ID of the resource that is being migrated.\nThis can be a VM ID, deployment ID, etc. depending on the type of the migration.","type":"string"},"resourceType":{"description":"ResourceType is the type of the resource that is being migrated.\n\nPossible values:\n- vm\n- deployment","type":"string"},"status":{"description":"Status is the status of the resource migration.\nWhen this field is set to 'accepted', the migration will take place and then automatically be deleted.","type":"string"},"type":{"description":"Type is the type of the resource migration.\n\nPossible values:\n- updateOwner","type":"string"},"updateOwner":{"description":"UpdateOwner is the set of parameters that are required for the updateOwner migration type.\nIt is empty if the migration type is not updateOwner.","properties":{"ownerId":{"type":"string"}},"type":"object"},"userId":{"description":"UserID is the ID of the user who initiated the migration.","type":"string"}},"type":"object"},"body.Role":{"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"items":{"type":"string"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"}},"type":"object"},"body.SmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.SmRead":{"properties":{"createdAt":{"type":"string"},"id":{"type":"string"},"ownerId":{"type":"string"},"url":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.SystemCapacities":{"properties":{"clusters":{"description":"Per Cluster","items":{"$ref":"#/components/schemas/body.ClusterCapacities"},"type":"array","uniqueItems":false},"cpuCore":{"$ref":"#/components/schemas/body.CpuCoreCapacities"},"gpu":{"$ref":"#/components/schemas/body.GpuCapacities"},"hosts":{"description":"Per Host","items":{"$ref":"#/components/schemas/body.HostCapacities"},"type":"array","uniqueItems":false},"ram":{"$ref":"#/components/schemas/body.RamCapacities"}},"type":"object"},"body.SystemStats":{"properties":{"k8s":{"$ref":"#/components/schemas/body.K8sStats"}},"type":"object"},"body.SystemStatus":{"properties":{"hosts":{"items":{"$ref":"#/components/schemas/body.HostStatus"},"type":"array","uniqueItems":false}},"type":"object"},"body.TeamCreate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberCreate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"required":["name"],"type":"object"},"body.TeamMember":{"properties":{"addedAt":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"joinedAt":{"type":"string"},"lastName":{"type":"string"},"memberStatus":{"type":"string"},"teamRole":{"type":"string"},"username":{"type":"string"}},"type":"object"},"body.TeamMemberCreate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamMemberUpdate":{"properties":{"id":{"type":"string"},"teamRole":{"description":"default to MemberRoleAdmin right now","type":"string"}},"required":["id"],"type":"object"},"body.TeamRead":{"properties":{"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMember"},"type":"array","uniqueItems":false},"name":{"type":"string"},"ownerId":{"type":"string"},"resources":{"items":{"$ref":"#/components/schemas/body.TeamResource"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"}},"type":"object"},"body.TeamResource":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"type":"object"},"body.TeamUpdate":{"properties":{"description":{"maxLength":1000,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/body.TeamMemberUpdate"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"name":{"maxLength":100,"minLength":1,"type":"string"},"resources":{"items":{"type":"string"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.TimestampedSystemCapacities":{"properties":{"capacities":{"$ref":"#/components/schemas/body.SystemCapacities"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStats":{"properties":{"stats":{"$ref":"#/components/schemas/body.SystemStats"},"timestamp":{"type":"string"}},"type":"object"},"body.TimestampedSystemStatus":{"properties":{"status":{"$ref":"#/components/schemas/body.SystemStatus"},"timestamp":{"type":"string"}},"type":"object"},"body.Usage":{"properties":{"cpuCores":{"type":"number"},"diskSize":{"type":"integer"},"ram":{"type":"number"}},"type":"object"},"body.UserData":{"properties":{"key":{"maxLength":255,"minLength":1,"type":"string"},"value":{"maxLength":255,"minLength":1,"type":"string"}},"required":["key","value"],"type":"object"},"body.UserRead":{"properties":{"admin":{"type":"boolean"},"apiKeys":{"items":{"$ref":"#/components/schemas/body.ApiKey"},"type":"array","uniqueItems":false},"email":{"type":"string"},"firstName":{"type":"string"},"gravatarUrl":{"type":"string"},"id":{"type":"string"},"lastName":{"type":"string"},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"type":"array","uniqueItems":false},"quota":{"$ref":"#/components/schemas/body.Quota"},"role":{"$ref":"#/components/schemas/body.Role"},"storageUrl":{"type":"string"},"usage":{"$ref":"#/components/schemas/body.Usage"},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"type":"array","uniqueItems":false},"username":{"type":"string"}},"type":"object"},"body.UserUpdate":{"properties":{"apiKeys":{"description":"ApiKeys specifies the API keys that should remain. If an API key is not in this list, it will be deleted.\nHowever, API keys cannot be created, use /apiKeys endpoint to create new API keys.","items":{"$ref":"#/components/schemas/body.ApiKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"publicKeys":{"items":{"$ref":"#/components/schemas/body.PublicKey"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false},"userData":{"items":{"$ref":"#/components/schemas/body.UserData"},"maxItems":100,"minItems":0,"type":"array","uniqueItems":false}},"type":"object"},"body.VmActionCreate":{"properties":{"action":{"enum":["start","stop","restart","repair"],"type":"string"}},"required":["action"],"type":"object"},"body.VmActionCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmCreate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"diskSize":{"minimum":10,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortCreate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"},"sshPublicKey":{"type":"string"},"zone":{"type":"string"}},"required":["cpuCores","diskSize","name","ram","sshPublicKey"],"type":"object"},"body.VmCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmGpuLease":{"properties":{"activatedAt":{"description":"ActivatedAt specifies the time when the lease was activated. This is the time the user first attached the GPU\nor 1 day after the lease was created if the user did not attach the GPU.","type":"string"},"assignedAt":{"description":"AssignedAt specifies the time when the lease was assigned to the user.","type":"string"},"createdAt":{"type":"string"},"expiredAt":{"description":"ExpiredAt specifies the time when the lease expired.\nThis is only present if the lease is expired.","type":"string"},"expiresAt":{"description":"ExpiresAt specifies the time when the lease will expire.\nThis is only present if the lease is active.","type":"string"},"gpuGroupId":{"type":"string"},"id":{"type":"string"},"leaseDuration":{"type":"number"}},"type":"object"},"body.VmRead":{"properties":{"accessedAt":{"type":"string"},"createdAt":{"type":"string"},"gpu":{"$ref":"#/components/schemas/body.VmGpuLease"},"host":{"type":"string"},"id":{"type":"string"},"internalName":{"type":"string"},"name":{"type":"string"},"neverStale":{"type":"boolean"},"ownerId":{"type":"string"},"ports":{"items":{"$ref":"#/components/schemas/body.PortRead"},"type":"array","uniqueItems":false},"repairedAt":{"type":"string"},"specs":{"$ref":"#/components/schemas/body.VmSpecs"},"sshConnectionString":{"type":"string"},"sshPublicKey":{"type":"string"},"status":{"type":"string"},"teams":{"items":{"type":"string"},"type":"array","uniqueItems":false},"updatedAt":{"type":"string"},"zone":{"type":"string"}},"type":"object"},"body.VmSnapshotCreated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotDeleted":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.VmSnapshotRead":{"properties":{"created":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.VmSpecs":{"properties":{"cpuCores":{"type":"integer"},"diskSize":{"type":"integer"},"ram":{"type":"integer"}},"type":"object"},"body.VmUpdate":{"properties":{"cpuCores":{"minimum":1,"type":"integer"},"name":{"maxLength":30,"minLength":3,"type":"string"},"neverStale":{"type":"boolean"},"ports":{"items":{"$ref":"#/components/schemas/body.PortUpdate"},"maxItems":10,"minItems":0,"type":"array","uniqueItems":false},"ram":{"minimum":1,"type":"integer"}},"type":"object"},"body.VmUpdated":{"properties":{"id":{"type":"string"},"jobId":{"type":"string"}},"type":"object"},"body.Volume":{"properties":{"appPath":{"maxLength":255,"minLength":1,"type":"string"},"name":{"maxLength":30,"minLength":3,"type":"string"},"serverPath":{"maxLength":255,"minLength":1,"type":"string"}},"required":["appPath","name","serverPath"],"type":"object"},"body.WorkerStatusRead":{"properties":{"name":{"type":"string"},"reportedAt":{"type":"string"},"status":{"type":"string"}},"type":"object"},"body.ZoneEndpoints":{"properties":{"deployment":{"type":"string"},"storage":{"type":"string"},"vm":{"type":"string"},"vmApp":{"type":"string"}},"type":"object"},"body.ZoneRead":{"properties":{"capabilities":{"items":{"type":"string"},"type":"array","uniqueItems":false},"description":{"type":"string"},"enabled":{"type":"boolean"},"endpoints":{"$ref":"#/components/schemas/body.ZoneEndpoints"},"legacy":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"sys.Error":{"properties":{"code":{"type":"string"},"msg":{"type":"string"}},"type":"object"},"sys.ErrorResponse":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/sys.Error"},"type":"array","uniqueItems":false}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"in":"header","name":"X-Api-Key","type":"apiKey"},"KeycloakOAuth":{"flows":{"authorizationCode":{"authorizationUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/auth","tokenUrl":"https://iam.cloud.cbh.kth.se/realms/cloud/protocol/openid-connect/token"}},"in":"header","type":"oauth2"}}}, "info": {"contact":{"name":"Support","url":"https://github.com/kthcloud/go-deploy"},"description":"This is the API explorer for the go-deploy API. You can use it as a reference for the API endpoints.","license":{"name":"MIT License","url":"https://github.com/kthcloud/go-deploy?tab=MIT-1-ov-file#readme"},"termsOfService":"http://swagger.io/terms/","title":"go-deploy API","version":"1.0"}, "externalDocs": {"description":"","url":""}, "paths": {"/v2/deployments":{"get":{"description":"List deployments","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Include shared","in":"query","name":"shared","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.DeploymentRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List deployments","tags":["Deployment"]},"post":{"description":"Create deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreate"}}},"description":"Deployment body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}":{"delete":{"description":"Delete deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete deployment","tags":["Deployment"]},"get":{"description":"Get deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get deployment","tags":["Deployment"]},"post":{"description":"Update deployment","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdate"}}},"description":"Deployment update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update deployment","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/ciConfig":{"get":{"description":"Get CI config","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.CiConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get CI config","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/command":{"post":{"description":"Do command","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DeploymentCommand"}}},"description":"Command body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Do command","tags":["Deployment"]}},"/v2/deployments/{deploymentId}/logs":{"get":{"description":"Get logs using Server-Sent Events","parameters":[{"description":"Deployment ID","in":"path","name":"deploymentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get logs using Server-Sent Events","tags":["Deployment"]}},"/v2/discover":{"get":{"description":"Discover","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.DiscoverRead"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Discover","tags":["Discover"]}},"/v2/gpuGroups":{"get":{"description":"List GPU groups","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuGroupRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU groups","tags":["GpuGroup"]}},"/v2/gpuGroups/{gpuGroupId}":{"get":{"description":"Get GPU group","parameters":[{"description":"GPU group ID","in":"path","name":"gpuGroupId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuGroupRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU group","tags":["GpuGroup"]}},"/v2/gpuLeases":{"get":{"description":"List GPU leases","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by VM ID","in":"query","name":"vmId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.GpuLeaseRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List GPU leases","tags":["GpuLease"]},"post":{"description":"Create GPU lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create GPU Lease","tags":["GpuLease"]}},"/v2/gpuLeases/{gpuLeaseId}":{"delete":{"description":"Delete GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete GPU lease","tags":["GpuLease"]},"get":{"description":"Get GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get GPU lease","tags":["GpuLease"]},"post":{"description":"Update GPU lease","parameters":[{"description":"GPU lease ID","in":"path","name":"gpuLeaseId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdate"}}},"description":"GPU lease","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.GpuLeaseUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update GPU lease","tags":["GpuLease"]}},"/v2/hooks/harbor":{"post":{"description":"Handle Harbor hook","parameters":[{"description":"Basic auth token","in":"header","name":"Authorization","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.HarborWebhook"}}},"description":"Harbor webhook body","required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Handle Harbor hook","tags":["Deployment"]}},"/v2/hosts":{"get":{"description":"List Hosts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostRead"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List Hosts","tags":["Host"]}},"/v2/hosts/verbose":{"get":{"description":"List Hosts verbose","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.HostVerboseRead"},"type":"array"}}},"description":"OK"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List Hosts verbose","tags":["Host"]}},"/v2/jobs":{"get":{"description":"List jobs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Filter by type","in":"query","name":"type","schema":{"type":"string"}},{"description":"Filter by status","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.JobRead"},"type":"array"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List jobs","tags":["Job"]}},"/v2/jobs/{jobId}":{"get":{"description":"GetJob job by id","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"GetJob job by id","tags":["Job"]},"post":{"description":"Update job. Only allowed for admins.","parameters":[{"description":"Job ID","in":"path","name":"jobId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobUpdate"}}},"description":"Job update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.JobRead"}}},"description":"OK"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update job","tags":["Job"]}},"/v2/metrics":{"get":{"description":"Get metrics","responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Get metrics","tags":["Metrics"]}},"/v2/notifications":{"get":{"description":"List notifications","parameters":[{"description":"List all notifications","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.NotificationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List notifications","tags":["Notification"]}},"/v2/notifications/{notificationId}":{"delete":{"description":"Delete notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete notification","tags":["Notification"]},"get":{"description":"Get notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get notification","tags":["Notification"]},"post":{"description":"Update notification","parameters":[{"description":"Notification ID","in":"path","name":"notificationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.NotificationUpdate"}}},"description":"Notification update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update notification","tags":["Notification"]}},"/v2/register":{"get":{"description":"Register resource","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"Register resource","tags":["Register"]}},"/v2/resourceMigrations":{"get":{"description":"List resource migrations","parameters":[{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ResourceMigrationRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List resource migrations","tags":["ResourceMigration"]},"post":{"description":"Create resource migration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreate"}}},"description":"Resource Migration Create","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create resource migration","tags":["ResourceMigration"]}},"/v2/resourceMigrations/{resourceMigrationId}":{"delete":{"description":"Delete resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete resource migration","tags":["ResourceMigration"]},"get":{"description":"Get resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get resource migration","tags":["ResourceMigration"]},"post":{"description":"Update resource migration","parameters":[{"description":"Resource Migration ID","in":"path","name":"resourceMigrationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdate"}}},"description":"Resource Migration Update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ResourceMigrationUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update resource migration","tags":["ResourceMigration"]}},"/v2/snapshots":{"get":{"description":"List snapshots","parameters":[{"description":"Filter by VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmSnapshotRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Locked"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List snapshots","tags":["Snapshot"]},"post":{"description":"Create snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create snapshot","tags":["Snapshot"]}},"/v2/storageManagers":{"get":{"description":"Get storage manager list","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.SmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager list","tags":["StorageManager"]}},"/v2/storageManagers/{storageManagerId}":{"delete":{"description":"Delete storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete storage manager","tags":["StorageManager"]},"get":{"description":"Get storage manager","parameters":[{"description":"Storage manager ID","in":"path","name":"storageManagerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.SmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get storage manager","tags":["StorageManager"]}},"/v2/systemCapacities":{"get":{"description":"List system capacities","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemCapacities"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system capacities","tags":["System"]}},"/v2/systemStats":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStats"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/systemStatus":{"get":{"description":"List system stats","parameters":[{"description":"n","in":"query","name":"n","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TimestampedSystemStatus"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List system stats","tags":["System"]}},"/v2/teams":{"get":{"description":"List teams","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.TeamRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List teams","tags":["Team"]},"post":{"description":"Create team","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamCreate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create team","tags":["Team"]}},"/v2/teams/{teamId}":{"delete":{"description":"Delete team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete team","tags":["Team"]},"get":{"description":"Get team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get team","tags":["Team"]},"post":{"description":"Update team","parameters":[{"description":"Team ID","in":"path","name":"teamId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamUpdate"}}},"description":"Team","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.TeamRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.BindingError"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update team","tags":["Team"]}},"/v2/users":{"get":{"description":"List users","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}},{"description":"Search query","in":"query","name":"search","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.UserRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List users","tags":["User"]}},"/v2/users/{userId}":{"get":{"description":"Get user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}},{"description":"Discovery mode","in":"query","name":"discover","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get user","tags":["User"]},"post":{"description":"Update user","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserUpdate"}}},"description":"User update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.UserRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update user","tags":["User"]}},"/v2/users/{userId}/apiKeys":{"post":{"description":"Create API key","parameters":[{"description":"User ID","in":"path","name":"userId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreate"}}},"description":"API key create body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.ApiKeyCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create API key","tags":["User"]}},"/v2/vmActions":{"post":{"description":"Creates a new action","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreate"}}},"description":"actions body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmActionCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Creates a new action","tags":["VmAction"]}},"/v2/vms":{"get":{"description":"List VMs","parameters":[{"description":"List all","in":"query","name":"all","schema":{"type":"boolean"}},{"description":"Filter by user ID","in":"query","name":"userId","schema":{"type":"string"}},{"description":"Page number","in":"query","name":"page","schema":{"type":"integer"}},{"description":"Number of items per page","in":"query","name":"pageSize","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.VmRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List VMs","tags":["VM"]},"post":{"description":"Create VM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreate"}}},"description":"VM body","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmCreated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Create VM","tags":["VM"]}},"/v2/vms/{vmId}":{"delete":{"description":"Delete VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete VM","tags":["VM"]},"get":{"description":"Get VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get VM","tags":["VM"]},"post":{"description":"Update VM","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdate"}}},"description":"VM update","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmUpdated"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Update VM","tags":["VM"]}},"/v2/vms/{vmId}/snapshot/{snapshotId}":{"delete":{"description":"Delete snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotDeleted"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Delete snapshot","tags":["Snapshot"]},"post":{"description":"Get snapshot","parameters":[{"description":"VM ID","in":"path","name":"vmId","required":true,"schema":{"type":"string"}},{"description":"Snapshot ID","in":"path","name":"snapshotId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/body.VmSnapshotRead"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"Get snapshot","tags":["Snapshot"]}},"/v2/workerStatus":{"get":{"description":"List of worker status","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.WorkerStatusRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"summary":"List worker status","tags":["Status"]}},"/v2/zones":{"get":{"description":"List zones","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/body.ZoneRead"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/sys.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"ApiKeyAuth":[]},{"KeycloakOAuth":[]}],"summary":"List zones","tags":["Zone"]}}}, diff --git a/docs/api/v2/V2_swagger.yaml b/docs/api/v2/V2_swagger.yaml index 9dc5f5c9..1003b712 100644 --- a/docs/api/v2/V2_swagger.yaml +++ b/docs/api/v2/V2_swagger.yaml @@ -244,6 +244,11 @@ components: uniqueItems: false internalPort: type: integer + internalPorts: + items: + type: integer + type: array + uniqueItems: false name: type: string neverStale: diff --git a/export/types/v2/body/index.ts b/export/types/v2/body/index.ts index 3f4f0f47..e35d8c49 100644 --- a/export/types/v2/body/index.ts +++ b/export/types/v2/body/index.ts @@ -41,6 +41,7 @@ export interface DeploymentRead { initCommands: string[]; args: string[]; internalPort: number /* int */; + internalPorts: number /* int */[]; image?: string; healthCheckPath?: string; customDomain?: CustomDomainRead; diff --git a/pkg/db/resources/deployment_repo/db.go b/pkg/db/resources/deployment_repo/db.go index 7059faa8..0d5c09e5 100644 --- a/pkg/db/resources/deployment_repo/db.go +++ b/pkg/db/resources/deployment_repo/db.go @@ -133,6 +133,7 @@ func (client *Client) UpdateWithParams(id string, params *model.DeploymentUpdate db.AddIfNotNil(&setUpdate, "name", params.Name) db.AddIfNotNil(&setUpdate, "ownerId", params.OwnerID) db.AddIfNotNil(&setUpdate, "apps.main.internalPort", params.InternalPort) + db.AddIfNotNil(&setUpdate, "apps.main.internalPorts", params.InternalPorts) db.AddIfNotNil(&setUpdate, "apps.main.envs", params.Envs) db.AddIfNotNil(&setUpdate, "apps.main.volumes", params.Volumes) db.AddIfNotNil(&setUpdate, "apps.main.initCommands", params.InitCommands) From d68863218c91328e2952477ea466debe38306935 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 02:56:02 +0200 Subject: [PATCH 30/36] fix typo on bson binding key --- dto/v2/body/deployment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dto/v2/body/deployment.go b/dto/v2/body/deployment.go index 2b3367ac..2151fc51 100644 --- a/dto/v2/body/deployment.go +++ b/dto/v2/body/deployment.go @@ -25,7 +25,7 @@ type DeploymentRead struct { InitCommands []string `json:"initCommands"` Args []string `json:"args"` InternalPort int `json:"internalPort"` - InternalPorts []int `json:"internalPorts"` + InternalPorts []int `json:"internalPorts,omitempty"` Image *string `json:"image,omitempty"` HealthCheckPath *string `json:"healthCheckPath,omitempty"` CustomDomain *CustomDomainRead `json:"customDomain,omitempty"` From 0406ccbb8aafd86d8bf3dbf41ec0d7c707f0b8d6 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 02:56:26 +0200 Subject: [PATCH 31/36] fix typo on bson binding --- models/model/deployment_related.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/model/deployment_related.go b/models/model/deployment_related.go index f71ef34e..a46d0302 100644 --- a/models/model/deployment_related.go +++ b/models/model/deployment_related.go @@ -38,7 +38,7 @@ type App struct { Image string `bson:"image"` InternalPort int `bson:"internalPort"` - InternalPorts []int `bson:"internallPorts"` + InternalPorts []int `bson:"internalPorts"` Envs []DeploymentEnv `bson:"envs"` Volumes []DeploymentVolume `bson:"volumes"` Visibility string `bson:"visibility"` From d354e153e46892ab4d4f5978d80405aff42fe036 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 03:53:30 +0200 Subject: [PATCH 32/36] fix conv to dto --- models/model/deployment_convert.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/models/model/deployment_convert.go b/models/model/deployment_convert.go index 4b128975..06770294 100644 --- a/models/model/deployment_convert.go +++ b/models/model/deployment_convert.go @@ -26,15 +26,17 @@ func (deployment *Deployment) ToDTO(smURL *string, externalPort *int, teams []st Value: fmt.Sprintf("%d", app.InternalPort), }) - portsStr := make([]string, len(app.InternalPorts)) - for i, port := range app.InternalPorts { - portsStr[i] = strconv.Itoa(port) - } + if len(app.InternalPorts) > 0 { + portsStr := make([]string, len(app.InternalPorts)) + for i, port := range app.InternalPorts { + portsStr[i] = strconv.Itoa(port) + } - envs = append(envs, body.Env{ - Name: "INTERNAL_PORTS", - Value: strings.Join(portsStr, ","), - }) + envs = append(envs, body.Env{ + Name: "INTERNAL_PORTS", + Value: strings.Join(portsStr, ","), + }) + } for i, env := range app.Envs { envs[i] = body.Env{ From 3d97808b135ce179c2d5764bb0cf1991bd1c6738 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 04:03:42 +0200 Subject: [PATCH 33/36] only set env if it is provided --- .../v2/deployments/resources/k8s_generator.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/service/v2/deployments/resources/k8s_generator.go b/service/v2/deployments/resources/k8s_generator.go index 8e85c3bc..3a4dd4f2 100644 --- a/service/v2/deployments/resources/k8s_generator.go +++ b/service/v2/deployments/resources/k8s_generator.go @@ -83,15 +83,17 @@ func (kg *K8sGenerator) Deployments() []models.DeploymentPublic { Value: fmt.Sprintf("%d", mainApp.InternalPort), }) - portsStr := make([]string, len(mainApp.InternalPorts)) - for i, port := range mainApp.InternalPorts { - portsStr[i] = strconv.Itoa(port) - } + if len(mainApp.InternalPorts) > 0 { + portsStr := make([]string, len(mainApp.InternalPorts)) + for i, port := range mainApp.InternalPorts { + portsStr[i] = strconv.Itoa(port) + } - k8sEnvs = append(k8sEnvs, models.EnvVar{ - Name: "INTERNAL_PORTS", - Value: strings.Join(portsStr, ","), - }) + k8sEnvs = append(k8sEnvs, models.EnvVar{ + Name: "INTERNAL_PORTS", + Value: strings.Join(portsStr, ","), + }) + } k8sVolumes := make([]models.Volume, len(mainApp.Volumes)) for i, volume := range mainApp.Volumes { From 639cc68d49612b3e793b1739075201f3e05e17b4 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 07:41:27 +0200 Subject: [PATCH 34/36] fix conversion related issues --- models/model/deployment_convert.go | 59 ++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/models/model/deployment_convert.go b/models/model/deployment_convert.go index 06770294..669781d7 100644 --- a/models/model/deployment_convert.go +++ b/models/model/deployment_convert.go @@ -2,6 +2,7 @@ package model import ( "fmt" + "slices" "strconv" "strings" @@ -21,28 +22,56 @@ func (deployment *Deployment) ToDTO(smURL *string, externalPort *int, teams []st envs := make([]body.Env, len(app.Envs)) - envs = append(envs, body.Env{ - Name: "PORT", - Value: fmt.Sprintf("%d", app.InternalPort), - }) - - if len(app.InternalPorts) > 0 { - portsStr := make([]string, len(app.InternalPorts)) - for i, port := range app.InternalPorts { - portsStr[i] = strconv.Itoa(port) + portIndex := -1 + internalPortIndex := -1 + for i, env := range app.Envs { + if env.Name == "PORT" { + portIndex = i + continue + } else if env.Name == "INTERNAL_PORTS" { + internalPortIndex = i + continue } + envs[i] = body.Env{ + Name: env.Name, + Value: env.Value, + } + } + if portIndex == -1 { envs = append(envs, body.Env{ - Name: "INTERNAL_PORTS", - Value: strings.Join(portsStr, ","), + Name: "PORT", + Value: fmt.Sprintf("%d", app.InternalPort), }) + } else { + envs[portIndex] = body.Env{ + Name: "PORT", + Value: fmt.Sprintf("%d", app.InternalPort), + } } + if internalPortIndex == -1 { + if len(app.InternalPorts) > 0 { + portsStr := make([]string, len(app.InternalPorts)) + for i, port := range app.InternalPorts { + portsStr[i] = fmt.Sprintf("%d", port) + } - for i, env := range app.Envs { - envs[i] = body.Env{ - Name: env.Name, - Value: env.Value, + envs = append(envs, body.Env{ + Name: "INTERNAL_PORTS", + Value: strings.Join(portsStr, ","), + }) } + } else if len(app.InternalPorts) > 0 { + portsStr := make([]string, len(app.InternalPorts)) + for i, port := range app.InternalPorts { + portsStr[i] = fmt.Sprintf("%d", port) + } + envs[internalPortIndex] = body.Env{ + Name: "INTERNAL_PORTS", + Value: strings.Join(portsStr, ","), + } + } else { + envs = slices.Delete(envs, internalPortIndex, internalPortIndex+1) } volumes := make([]body.Volume, len(app.Volumes)) From 1811cdcb2f87910d9881e9d91ff727b8ce0f6a45 Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 22 Apr 2025 07:48:48 +0200 Subject: [PATCH 35/36] update tygo types --- export/types/v2/body/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/export/types/v2/body/index.ts b/export/types/v2/body/index.ts index e35d8c49..062e99a6 100644 --- a/export/types/v2/body/index.ts +++ b/export/types/v2/body/index.ts @@ -41,7 +41,7 @@ export interface DeploymentRead { initCommands: string[]; args: string[]; internalPort: number /* int */; - internalPorts: number /* int */[]; + internalPorts?: number /* int */[]; image?: string; healthCheckPath?: string; customDomain?: CustomDomainRead; From ac2ec4ec36800daa6a12289aa8b941e663611c6b Mon Sep 17 00:00:00 2001 From: Philip Zingmark Date: Tue, 9 Sep 2025 12:02:17 +0200 Subject: [PATCH 36/36] Set filebrowser image to track a tag before breaking changes from their side --- service/v2/sms/resources/k8s_generator.go | 39 +++++++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/service/v2/sms/resources/k8s_generator.go b/service/v2/sms/resources/k8s_generator.go index 7f95bbda..9283ef59 100644 --- a/service/v2/sms/resources/k8s_generator.go +++ b/service/v2/sms/resources/k8s_generator.go @@ -2,6 +2,11 @@ package resources import ( "fmt" + "math" + "path" + "slices" + "strings" + configModels "github.com/kthcloud/go-deploy/models/config" "github.com/kthcloud/go-deploy/models/model" "github.com/kthcloud/go-deploy/pkg/config" @@ -14,15 +19,14 @@ import ( "github.com/kthcloud/go-deploy/service/generators" "github.com/kthcloud/go-deploy/utils" v1 "k8s.io/api/core/v1" - "math" - "path" - "slices" - "strings" ) +const DefaultFilebrowserImage = "filebrowser/filebrowser:v2.32.3" + type K8sGenerator struct { generators.K8sGeneratorBase + image *string namespace string client *k8s.Client @@ -30,13 +34,27 @@ type K8sGenerator struct { zone *configModels.Zone } -func K8s(sm *model.SM, zone *configModels.Zone, client *k8s.Client, namespace string) *K8sGenerator { - return &K8sGenerator{ +type K8SGeneratorOption func(kg *K8sGenerator) + +func WithImage(image string) K8SGeneratorOption { + return func(kg *K8sGenerator) { + kg.image = utils.StrPtr(image) + } +} + +func K8s(sm *model.SM, zone *configModels.Zone, client *k8s.Client, namespace string, opts ...K8SGeneratorOption) *K8sGenerator { + kg := &K8sGenerator{ namespace: namespace, client: client, sm: sm, zone: zone, } + + for _, opt := range opts { + opt(kg) + } + + return kg } func (kg *K8sGenerator) Namespace() *models.NamespacePublic { @@ -86,11 +104,18 @@ func (kg *K8sGenerator) Deployments() []models.DeploymentPublic { "--port=80", } + image := func() string { + if kg.image != nil { + return *kg.image + } + return DefaultFilebrowserImage + }() + filebrowser := models.DeploymentPublic{ Name: smName(kg.sm.OwnerID), Namespace: kg.namespace, Labels: map[string]string{"owner-id": kg.sm.OwnerID}, - Image: "filebrowser/filebrowser", + Image: image, ImagePullSecrets: make([]string, 0), EnvVars: make([]models.EnvVar, 0), Resources: models.Resources{