From 417bf73e448964c0455daf3c72897b650ff551e7 Mon Sep 17 00:00:00 2001 From: Saeed Vaziry <61919774+saeedvaziry@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:49:57 +0100 Subject: [PATCH] API Feature (#334) --- .env.example | 4 + .scribe/.filehashes | 4 + .scribe/auth.md | 7 + .scribe/endpoints.cache/00.yaml | 310 + .scribe/endpoints.cache/01.yaml | 286 + .scribe/endpoints.cache/02.yaml | 392 + .scribe/endpoints.cache/03.yaml | 334 + .scribe/endpoints.cache/04.yaml | 46 + .scribe/endpoints.cache/05.yaml | 260 + .scribe/endpoints.cache/06.yaml | 516 + .scribe/endpoints.cache/07.yaml | 372 + .scribe/endpoints.cache/08.yaml | 235 + .scribe/endpoints.cache/09.yaml | 578 + .scribe/endpoints.cache/10.yaml | 392 + .scribe/endpoints.cache/11.yaml | 430 + .scribe/endpoints.cache/12.yaml | 372 + .scribe/endpoints/00.yaml | 308 + .scribe/endpoints/01.yaml | 284 + .scribe/endpoints/02.yaml | 390 + .scribe/endpoints/03.yaml | 332 + .scribe/endpoints/04.yaml | 44 + .scribe/endpoints/05.yaml | 258 + .scribe/endpoints/06.yaml | 514 + .scribe/endpoints/07.yaml | 370 + .scribe/endpoints/08.yaml | 233 + .scribe/endpoints/09.yaml | 576 + .scribe/endpoints/10.yaml | 390 + .scribe/endpoints/11.yaml | 428 + .scribe/endpoints/12.yaml | 370 + .scribe/endpoints/custom.0.yaml | 53 + .scribe/intro.md | 13 + app/Actions/CronJob/CreateCronJob.php | 4 +- app/Actions/Database/CreateDatabaseUser.php | 2 +- app/Actions/Database/LinkUser.php | 6 +- app/Actions/Server/CreateServer.php | 28 +- .../ServerProvider/CreateServerProvider.php | 17 +- .../ServerProvider/DeleteServerProvider.php | 9 +- .../ServerProvider/EditServerProvider.php | 8 +- app/Actions/Service/Uninstall.php | 3 + app/Actions/Site/CreateSite.php | 10 +- .../SourceControl/ConnectSourceControl.php | 7 +- .../SourceControl/DeleteSourceControl.php | 5 +- .../SourceControl/EditSourceControl.php | 34 +- .../StorageProvider/CreateStorageProvider.php | 7 +- .../StorageProvider/DeleteStorageProvider.php | 9 +- .../StorageProvider/EditStorageProvider.php | 8 +- app/Actions/Tag/AttachTag.php | 61 - app/Actions/Tag/DetachTag.php | 39 - app/Console/Commands/CreateUserCommand.php | 4 +- app/Enums/Database.php | 4 + app/Enums/PHP.php | 30 + app/Exceptions/Handler.php | 15 +- app/Http/Controllers/API/AgentController.php | 2 + .../Controllers/API/CronJobController.php | 97 + .../Controllers/API/DatabaseController.php | 94 + .../API/DatabaseUserController.php | 114 + .../API/FirewallRuleController.php | 99 + .../Controllers/API/GitHookController.php | 2 + app/Http/Controllers/API/HealthController.php | 8 + .../Controllers/API/ProjectController.php | 89 + app/Http/Controllers/API/ServerController.php | 131 + .../API/ServerProviderController.php | 116 + .../API/ServerSSHKeyController.php | 92 + .../Controllers/API/ServiceController.php | 146 + app/Http/Controllers/API/SiteController.php | 105 + .../API/SourceControlController.php | 121 + .../API/StorageProviderController.php | 116 + app/Http/Controllers/ConsoleController.php | 4 + app/Http/Kernel.php | 4 + app/Http/Middleware/Authenticate.php | 2 +- .../Middleware/CanSeeProjectMiddleware.php | 26 + app/Http/Middleware/HasProjectMiddleware.php | 32 + app/Http/Resources/CronJobResource.php | 25 + app/Http/Resources/DatabaseResource.php | 23 + app/Http/Resources/DatabaseUserResource.php | 25 + app/Http/Resources/FirewallRuleResource.php | 28 + app/Http/Resources/ProjectResource.php | 21 + app/Http/Resources/ServerProviderResource.php | 24 + app/Http/Resources/ServerResource.php | 42 + app/Http/Resources/ServiceResource.php | 28 + app/Http/Resources/SiteResource.php | 34 + app/Http/Resources/SourceControlResource.php | 24 + app/Http/Resources/SshKeyResource.php | 22 + .../Resources/StorageProviderResource.php | 24 + app/Http/Resources/UserResource.php | 22 + app/Models/PersonalAccessToken.php | 23 + app/Models/User.php | 30 +- app/Policies/PersonalAccessTokenPolicy.php | 42 + app/Policies/ServerPolicy.php | 9 +- app/Policies/ServerProviderPolicy.php | 13 +- app/Providers/AppServiceProvider.php | 4 + app/Providers/RouteServiceProvider.php | 10 - app/Providers/WebServiceProvider.php | 2 + .../Services/ProcessManager/Supervisor.php | 2 - .../AbstractSourceControlProvider.php | 15 +- app/SourceControlProviders/Gitlab.php | 12 + .../SourceControlProvider.php | 4 + app/Support/helpers.php | 7 +- app/Traits/Enum.php | 13 + app/Web/Pages/Servers/Index.php | 32 +- .../Pages/Servers/Logs/Widgets/LogsList.php | 13 +- app/Web/Pages/Servers/Settings.php | 3 +- app/Web/Pages/Servers/View.php | 2 +- app/Web/Pages/Settings/APIKeys/Index.php | 115 + .../Settings/APIKeys/Widgets/ApiKeysList.php | 62 + .../Widgets/NotificationChannelsList.php | 4 +- .../Projects/Widgets/SelectProject.php | 11 +- .../ServerProviders/Actions/Create.php | 26 +- .../Settings/ServerProviders/Actions/Edit.php | 2 +- .../SourceControls/Actions/Create.php | 2 +- .../Settings/SourceControls/Actions/Edit.php | 30 +- .../Widgets/SourceControlsList.php | 2 +- .../StorageProviders/Actions/Create.php | 2 +- .../StorageProviders/Actions/Edit.php | 2 +- composer.json | 5 +- composer.lock | 1100 +- config/route-attributes.php | 47 + config/scribe.php | 274 + database/factories/SourceControlFactory.php | 1 + public/api-docs/collection.json | 2898 ++++ public/api-docs/css/theme-default.print.css | 393 + public/api-docs/css/theme-default.style.css | 1090 ++ public/api-docs/images/navbar.png | Bin 0 -> 96 bytes public/api-docs/index.html | 12506 ++++++++++++++++ public/api-docs/js/theme-default-4.38.0.js | 149 + public/api-docs/js/tryitout-4.38.0.js | 289 + public/api-docs/openapi.yaml | 5259 +++++++ resources/svg/plug.svg | 6 + routes/api.php | 12 - routes/web.php | 7 - tests/Feature/API/CronjobTest.php | 79 + tests/Feature/API/DatabaseTest.php | 93 + tests/Feature/API/DatabaseUserTest.php | 146 + tests/Feature/API/FirewallTest.php | 77 + tests/Feature/API/ProjectsTest.php | 94 + tests/Feature/API/ServerProvidersTest.php | 174 + tests/Feature/API/ServerSshKeysTest.php | 109 + tests/Feature/API/ServerTest.php | 121 + tests/Feature/API/ServicesTest.php | 125 + tests/Feature/API/SitesTest.php | 92 + tests/Feature/API/SourceControlsTest.php | 134 + tests/Feature/API/StorageProvidersTest.php | 173 + tests/Feature/ServicesTest.php | 6 - 143 files changed, 36520 insertions(+), 586 deletions(-) create mode 100644 .scribe/.filehashes create mode 100644 .scribe/auth.md create mode 100644 .scribe/endpoints.cache/00.yaml create mode 100644 .scribe/endpoints.cache/01.yaml create mode 100644 .scribe/endpoints.cache/02.yaml create mode 100644 .scribe/endpoints.cache/03.yaml create mode 100644 .scribe/endpoints.cache/04.yaml create mode 100644 .scribe/endpoints.cache/05.yaml create mode 100644 .scribe/endpoints.cache/06.yaml create mode 100644 .scribe/endpoints.cache/07.yaml create mode 100644 .scribe/endpoints.cache/08.yaml create mode 100644 .scribe/endpoints.cache/09.yaml create mode 100644 .scribe/endpoints.cache/10.yaml create mode 100644 .scribe/endpoints.cache/11.yaml create mode 100644 .scribe/endpoints.cache/12.yaml create mode 100644 .scribe/endpoints/00.yaml create mode 100644 .scribe/endpoints/01.yaml create mode 100644 .scribe/endpoints/02.yaml create mode 100644 .scribe/endpoints/03.yaml create mode 100644 .scribe/endpoints/04.yaml create mode 100644 .scribe/endpoints/05.yaml create mode 100644 .scribe/endpoints/06.yaml create mode 100644 .scribe/endpoints/07.yaml create mode 100644 .scribe/endpoints/08.yaml create mode 100644 .scribe/endpoints/09.yaml create mode 100644 .scribe/endpoints/10.yaml create mode 100644 .scribe/endpoints/11.yaml create mode 100644 .scribe/endpoints/12.yaml create mode 100644 .scribe/endpoints/custom.0.yaml create mode 100644 .scribe/intro.md delete mode 100644 app/Actions/Tag/AttachTag.php delete mode 100644 app/Actions/Tag/DetachTag.php create mode 100644 app/Enums/PHP.php create mode 100644 app/Http/Controllers/API/CronJobController.php create mode 100644 app/Http/Controllers/API/DatabaseController.php create mode 100644 app/Http/Controllers/API/DatabaseUserController.php create mode 100644 app/Http/Controllers/API/FirewallRuleController.php create mode 100644 app/Http/Controllers/API/ProjectController.php create mode 100644 app/Http/Controllers/API/ServerController.php create mode 100644 app/Http/Controllers/API/ServerProviderController.php create mode 100644 app/Http/Controllers/API/ServerSSHKeyController.php create mode 100644 app/Http/Controllers/API/ServiceController.php create mode 100644 app/Http/Controllers/API/SiteController.php create mode 100644 app/Http/Controllers/API/SourceControlController.php create mode 100644 app/Http/Controllers/API/StorageProviderController.php create mode 100644 app/Http/Middleware/CanSeeProjectMiddleware.php create mode 100644 app/Http/Middleware/HasProjectMiddleware.php create mode 100644 app/Http/Resources/CronJobResource.php create mode 100644 app/Http/Resources/DatabaseResource.php create mode 100644 app/Http/Resources/DatabaseUserResource.php create mode 100644 app/Http/Resources/FirewallRuleResource.php create mode 100644 app/Http/Resources/ProjectResource.php create mode 100644 app/Http/Resources/ServerProviderResource.php create mode 100644 app/Http/Resources/ServerResource.php create mode 100644 app/Http/Resources/ServiceResource.php create mode 100644 app/Http/Resources/SiteResource.php create mode 100644 app/Http/Resources/SourceControlResource.php create mode 100644 app/Http/Resources/SshKeyResource.php create mode 100644 app/Http/Resources/StorageProviderResource.php create mode 100644 app/Http/Resources/UserResource.php create mode 100644 app/Models/PersonalAccessToken.php create mode 100644 app/Policies/PersonalAccessTokenPolicy.php create mode 100644 app/Traits/Enum.php create mode 100644 app/Web/Pages/Settings/APIKeys/Index.php create mode 100644 app/Web/Pages/Settings/APIKeys/Widgets/ApiKeysList.php create mode 100644 config/route-attributes.php create mode 100644 config/scribe.php create mode 100644 public/api-docs/collection.json create mode 100644 public/api-docs/css/theme-default.print.css create mode 100644 public/api-docs/css/theme-default.style.css create mode 100644 public/api-docs/images/navbar.png create mode 100644 public/api-docs/index.html create mode 100644 public/api-docs/js/theme-default-4.38.0.js create mode 100644 public/api-docs/js/tryitout-4.38.0.js create mode 100644 public/api-docs/openapi.yaml create mode 100644 resources/svg/plug.svg create mode 100644 tests/Feature/API/CronjobTest.php create mode 100644 tests/Feature/API/DatabaseTest.php create mode 100644 tests/Feature/API/DatabaseUserTest.php create mode 100644 tests/Feature/API/FirewallTest.php create mode 100644 tests/Feature/API/ProjectsTest.php create mode 100644 tests/Feature/API/ServerProvidersTest.php create mode 100644 tests/Feature/API/ServerSshKeysTest.php create mode 100644 tests/Feature/API/ServerTest.php create mode 100644 tests/Feature/API/ServicesTest.php create mode 100644 tests/Feature/API/SitesTest.php create mode 100644 tests/Feature/API/SourceControlsTest.php create mode 100644 tests/Feature/API/StorageProvidersTest.php diff --git a/.env.example b/.env.example index 224d6ac..97cd98e 100755 --- a/.env.example +++ b/.env.example @@ -14,3 +14,7 @@ MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="noreply@${APP_NAME}" MAIL_FROM_NAME="${APP_NAME}" + +APP_PORT=8000 + +SCRIBE_AUTH_KEY="YOUR-API-KEY" diff --git a/.scribe/.filehashes b/.scribe/.filehashes new file mode 100644 index 0000000..6541152 --- /dev/null +++ b/.scribe/.filehashes @@ -0,0 +1,4 @@ +# GENERATED. YOU SHOULDN'T MODIFY OR DELETE THIS FILE. +# Scribe uses this file to know when you change something manually in your docs. +.scribe/intro.md=98adb6862b118c06e02e4e22390feb6f +.scribe/auth.md=7fcc12b2e5a86fa9c49f509d348f3cc2 \ No newline at end of file diff --git a/.scribe/auth.md b/.scribe/auth.md new file mode 100644 index 0000000..64d11a3 --- /dev/null +++ b/.scribe/auth.md @@ -0,0 +1,7 @@ +# Authenticating requests + +To authenticate requests, include an **`Authorization`** header with the value **`"Bearer YOUR-API-KEY"`**. + +All authenticated endpoints are marked with a `requires authentication` badge in the documentation below. + +You can retrieve your token by visiting here diff --git a/.scribe/endpoints.cache/00.yaml b/.scribe/endpoints.cache/00.yaml new file mode 100644 index 0000000..6c5917c --- /dev/null +++ b/.scribe/endpoints.cache/00.yaml @@ -0,0 +1,310 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: cron-jobs +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all cron jobs.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null},{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6ed1gv5ak6hEPcaV8D3Z4bf' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new cron job.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + command: + name: command + description: '' + required: true + example: qui + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + user: + name: user + description: '' + required: true + example: root + type: string + enumValues: + - root + - vito + exampleWasSpecified: false + nullable: false + custom: [] + frequency: + name: frequency + description: 'Frequency of the cron job.' + required: true + example: '* * * * *' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + command: qui + user: root + frequency: '* * * * *' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer VEfc5h3gva68PkZ46Deabd1' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs/{cronJob_id}' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a cron job by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cronJob_id: + name: cronJob_id + description: 'The ID of the cronJob.' + required: true + example: 5 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + cronJob_id: 5 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 614DaP5vZ6edcaVEgfhk83b' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs/{cronJob_id}' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete cron job.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cronJob_id: + name: cronJob_id + description: 'The ID of the cronJob.' + required: true + example: 5 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + cronJob_id: 5 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gDV6bZ1dEckvf45P86eaha3' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/01.yaml b/.scribe/endpoints.cache/01.yaml new file mode 100644 index 0000000..8d899d6 --- /dev/null +++ b/.scribe/endpoints.cache/01.yaml @@ -0,0 +1,286 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: databases +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/databases' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all databases.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"name":"clockman","status":"ready","created_at":null,"updated_at":null},{"id":null,"server_id":null,"name":"wvonrueden","status":"ready","created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer efEV4g86bd5PZac6vak3Dh1' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/databases' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new database.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: '' + required: true + example: nesciunt + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: nesciunt + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"name":"johanna76","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 3E6VD14dvaekbaZfh6Pg8c5' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/databases/{id}' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a database by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the database.' + required: true + example: 6 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + id: 6 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"name":"chloe.huel","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer fb5hVc38e1aDP6ZvkgEda46' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/databases/{database_id}' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete database.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + database_id: + name: database_id + description: 'The ID of the database.' + required: true + example: 6 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + database_id: 6 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer cPVbhaZkfg5aEv46D183ed6' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/02.yaml b/.scribe/endpoints.cache/02.yaml new file mode 100644 index 0000000..1e34d84 --- /dev/null +++ b/.scribe/endpoints.cache/02.yaml @@ -0,0 +1,392 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: database-users +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/database-users' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all database users.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"username":"nyasia68","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"username":"madyson20","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer egc5VaDdvabfP6843k61hZE' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/database-users' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new database user.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + username: + name: username + description: '' + required: true + example: dignissimos + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + password: + name: password + description: '' + required: true + example: OK+XEG2) + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + host: + name: host + description: 'Host, if it is a remote user.' + required: true + example: '%' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + username: dignissimos + password: OK+XEG2) + host: '%' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"username":"amya.nitzsche","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 31hgfcvEb6Pkaa48D6dZ5Ve' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a database user by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + databaseUser_id: + name: databaseUser_id + description: 'The ID of the databaseUser.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + databaseUser_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"username":"bergstrom.ericka","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer aDv48631h5af6EdkcVbPZeg' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}/link' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: link + description: 'Link to databases' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + databaseUser_id: + name: databaseUser_id + description: 'The ID of the databaseUser.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + databaseUser_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + databases: + name: databases + description: 'Array of database names to link to the user.' + required: true + example: accusantium + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + databases: accusantium + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"username":"fmurray","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer cf8ZPhV1k3d5DaEva46beg6' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete database user.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + databaseUser_id: + name: databaseUser_id + description: 'The ID of the databaseUser.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + databaseUser_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer hdEvkbaPVf4cZ65a8631eDg' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/03.yaml b/.scribe/endpoints.cache/03.yaml new file mode 100644 index 0000000..69d289c --- /dev/null +++ b/.scribe/endpoints.cache/03.yaml @@ -0,0 +1,334 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: firewall-rules +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all firewall rules.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":18074,"source":"189.27.156.82","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":41088,"source":"86.177.121.87","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer vhkc4aPa6ZdeV8D3Ef156gb' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new firewall rule.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + type: + name: type + description: '' + required: true + example: allow + type: string + enumValues: + - allow + - deny + exampleWasSpecified: false + nullable: false + custom: [] + protocol: + name: protocol + description: '' + required: true + example: udp + type: string + enumValues: + - tcp + - udp + exampleWasSpecified: false + nullable: false + custom: [] + port: + name: port + description: '' + required: true + example: voluptates + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + source: + name: source + description: '' + required: true + example: saepe + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + mask: + name: mask + description: 'Mask for source IP.' + required: true + example: '0' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + type: allow + protocol: udp + port: voluptates + source: saepe + mask: '0' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":61992,"source":"47.222.76.48","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 1cEb5P66VeDkf8aahg3Zdv4' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules/{firewallRule_id}' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a firewall rule by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + firewallRule_id: + name: firewallRule_id + description: 'The ID of the firewallRule.' + required: true + example: 7 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + firewallRule_id: 7 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":43107,"source":"135.73.216.16","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6VaPhkD5vd1Z8e6E3cba4gf' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules/{firewallRule_id}' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete firewall rule.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + firewallRule_id: + name: firewallRule_id + description: 'The ID of the firewallRule.' + required: true + example: 7 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + firewallRule_id: 7 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer v81d5Efch636aVgZebaPkD4' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/04.yaml b/.scribe/endpoints.cache/04.yaml new file mode 100644 index 0000000..090e430 --- /dev/null +++ b/.scribe/endpoints.cache/04.yaml @@ -0,0 +1,46 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: general +description: '' +endpoints: + - + httpMethods: + - GET + uri: api/health + metadata: + groupName: general + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: health-check + description: '' + authenticated: false + custom: [] + headers: + Content-Type: application/json + Accept: application/json + urlParameters: [] + cleanUrlParameters: [] + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"success":true,"version":"2.0.0"}' + headers: + cache-control: 'no-cache, private' + content-type: application/json + x-ratelimit-limit: '60' + x-ratelimit-remaining: '59' + access-control-allow-origin: '*' + description: null + custom: [] + responseFields: [] + auth: [] + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/05.yaml b/.scribe/endpoints.cache/05.yaml new file mode 100644 index 0000000..24b3e7e --- /dev/null +++ b/.scribe/endpoints.cache/05.yaml @@ -0,0 +1,260 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: projects +description: '' +endpoints: + - + httpMethods: + - GET + uri: api/projects + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all projects.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: [] + cleanUrlParameters: [] + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":29,"name":"Zachary Lueilwitz","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":30,"name":"Mrs. Kiarra Heller IV","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer eb14DEPv6cdah65VfZgka38' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: api/projects + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: [] + cleanUrlParameters: [] + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the project.' + required: true + example: quos + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: quos + fileParameters: [] + responses: + - + status: 200 + content: '{"id":29,"name":"Hershel Spinka","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer V1E3566Pf4gkvh8dDZabeca' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{id}' + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a project by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + id: + name: id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":29,"name":"Emery Kiehn","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer haD6e36VZbkf4P8aEcvd15g' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{id}' + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: 'Update project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + id: + name: id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the project.' + required: true + example: ut + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: ut + fileParameters: [] + responses: + - + status: 200 + content: '{"id":29,"name":"Mable Prohaska","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer V14kPa5deva8Ebgc36f6hDZ' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}' + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer k1D68d5ePavVZag6h4fb3cE' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/06.yaml b/.scribe/endpoints.cache/06.yaml new file mode 100644 index 0000000..dd21f53 --- /dev/null +++ b/.scribe/endpoints.cache/06.yaml @@ -0,0 +1,516 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: servers +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all servers in a project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Dorthy Toy","ssh_user":"vito","ip":"172.132.95.155","local_ip":"118.57.197.65","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null},{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Carrie Sporer","ssh_user":"vito","ip":"184.242.162.173","local_ip":"135.244.50.22","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 8VE41PdZcvb6kgafD635ahe' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The server provider type' + required: true + example: et + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_provider: + name: server_provider + description: 'If the provider is not custom, the ID of the server provider profile' + required: true + example: digitalocean + type: string + enumValues: + - custom + - hetzner + - digitalocean + - linode + - vultr + exampleWasSpecified: false + nullable: false + custom: [] + region: + name: region + description: 'Provider region if the provider is not custom' + required: true + example: inventore + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + plan: + name: plan + description: 'Provider plan if the provider is not custom' + required: true + example: atque + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + ip: + name: ip + description: 'SSH IP address if the provider is custom' + required: true + example: quam + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + port: + name: port + description: 'SSH Port if the provider is custom' + required: true + example: nemo + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the server.' + required: true + example: perspiciatis + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + os: + name: os + description: 'The os of the server' + required: true + example: similique + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + type: + name: type + description: 'Server type' + required: true + example: regular + type: string + enumValues: + - regular + - database + exampleWasSpecified: false + nullable: false + custom: [] + webserver: + name: webserver + description: 'Web server' + required: true + example: none + type: string + enumValues: + - none + - nginx + exampleWasSpecified: false + nullable: false + custom: [] + database: + name: database + description: Database + required: true + example: none + type: string + enumValues: + - none + - mysql57 + - mysql80 + - mariadb103 + - mariadb104 + - mariadb103 + - postgresql12 + - postgresql13 + - postgresql14 + - postgresql15 + - postgresql16 + exampleWasSpecified: false + nullable: false + custom: [] + php: + name: php + description: 'PHP version' + required: true + example: '8.1' + type: string + enumValues: + - '7.0' + - '7.1' + - '7.2' + - '7.3' + - '7.4' + - '8.0' + - '8.1' + - '8.2' + - '8.3' + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: et + server_provider: digitalocean + region: inventore + plan: atque + ip: quam + port: nemo + name: perspiciatis + os: similique + type: regular + webserver: none + database: none + php: '8.1' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Flo Beer PhD","ssh_user":"vito","ip":"168.238.14.230","local_ip":"40.232.73.41","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer Z8g36aaV4E1bdcPfehDv65k' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{id}' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a server by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Stephany Ankunding","ssh_user":"vito","ip":"145.28.94.46","local_ip":"69.133.44.100","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer adD3EfP5hZ4vgbkV861eca6' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/reboot' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: reboot + description: 'Reboot a server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer P3ec6aagD4hbdV5fEk168vZ' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/upgrade' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: upgrade + description: 'Upgrade server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer P34ZV6D1bEegdvac8f5kh6a' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer ha6v5V41afkdPgcZbDEe386' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/07.yaml b/.scribe/endpoints.cache/07.yaml new file mode 100644 index 0000000..1ecfe23 --- /dev/null +++ b/.scribe/endpoints.cache/07.yaml @@ -0,0 +1,372 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: server-providers +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/server-providers' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":2,"project_id":null,"global":true,"name":"dolor","provider":"digitalocean","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":3,"project_id":null,"global":true,"name":"enim","provider":"digitalocean","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 1a6kb58vEP3fZdVhcea64gD' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/server-providers' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)' + required: true + example: autem + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the server provider.' + required: true + example: enim + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: culpa + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + key: + name: key + description: 'The key if provider requires key' + required: true + example: sit + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + secret: + name: secret + description: 'The secret if provider requires key' + required: true + example: voluptates + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: autem + name: enim + token: culpa + key: sit + secret: voluptates + fileParameters: [] + responses: + - + status: 200 + content: '{"id":2,"project_id":null,"global":true,"name":"eligendi","provider":"aws","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer PD3ZcaVdvgfa5k4be8E6h16' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/server-providers/{serverProvider_id}' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + serverProvider_id: + name: serverProvider_id + description: 'The ID of the serverProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + serverProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":2,"project_id":null,"global":true,"name":"architecto","provider":"digitalocean","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer DP45bg1aEadh8Z6Vke63fcv' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{project_id}/server-providers/{serverProvider_id}' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + serverProvider_id: + name: serverProvider_id + description: 'The ID of the serverProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + serverProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the server provider.' + required: true + example: minus + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + global: + name: global + description: 'Accessible in all projects' + required: true + example: false + type: string + enumValues: + - true + - false + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: minus + global: false + fileParameters: [] + responses: + - + status: 200 + content: '{"id":2,"project_id":null,"global":true,"name":"reiciendis","provider":"hetzner","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer bv1kdegh6fP8V56ZE4acaD3' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/server-providers/{serverProvider_id}' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + serverProvider_id: + name: serverProvider_id + description: 'The ID of the serverProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + serverProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer k6hb43Vf5Z1dv8aaeEDcg6P' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/08.yaml b/.scribe/endpoints.cache/08.yaml new file mode 100644 index 0000000..56e22d4 --- /dev/null +++ b/.scribe/endpoints.cache/08.yaml @@ -0,0 +1,235 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: ssh-keys +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/ssh-keys' + metadata: + groupName: ssh-keys + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all ssh keys.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"user":null,"name":"Dr. Reanna Braun","created_at":null,"updated_at":null},{"id":null,"user":null,"name":"Norene Fritsch","created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer dV1gcvfZ46Eh8ebaP5Da63k' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/ssh-keys' + metadata: + groupName: ssh-keys + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Deploy ssh key to server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + key_id: + name: key_id + description: 'The ID of the key.' + required: true + example: vero + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'Key name, required if key_id is not provided.' + required: true + example: voluptates + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + public_key: + name: public_key + description: 'Public Key, required if key_id is not provided.' + required: true + example: dolor + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + key_id: vero + name: voluptates + public_key: dolor + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"user":null,"name":"Sophia D''Amore","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gkadV36a5f8E6vhb14ZceDP' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/ssh-keys/{sshKey_id}' + metadata: + groupName: ssh-keys + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete ssh key from server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sshKey_id: + name: sshKey_id + description: 'The ID of the sshKey.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + sshKey_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer PfchD4Zge386abadE5kV61v' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/09.yaml b/.scribe/endpoints.cache/09.yaml new file mode 100644 index 0000000..782d360 --- /dev/null +++ b/.scribe/endpoints.cache/09.yaml @@ -0,0 +1,578 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: services +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/services' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all services.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"type":null,"type_data":null,"name":null,"version":null,"unit":null,"status":null,"is_default":null,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"type":null,"type_data":null,"name":null,"version":null,"unit":null,"status":null,"is_default":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer h6bDec51ak84ZVafgv3PE6d' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/services/{id}' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a service by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"type":null,"type_data":null,"name":null,"version":null,"unit":null,"status":null,"is_default":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer da4V3kfgZ6a86PchevED5b1' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/start' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: start + description: 'Start service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 86fdV5D6gv1E3ekaPZac4hb' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/stop' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: stop + description: 'Stop service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer kPZ563E1Vfgh4cbDad8vae6' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/restart' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: restart + description: 'Restart service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer fd14PaDb58gchv3ZVeaEk66' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/enable' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: enable + description: 'Enable service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer Dv1aVe6hZfkagdE356b4cP8' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/disable' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: disable + description: 'Disable service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6bdDc4Eah3ZV18kf6Pveag5' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 36kf84v6bVhE5gdPDeZ1caa' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/10.yaml b/.scribe/endpoints.cache/10.yaml new file mode 100644 index 0000000..3acdaf0 --- /dev/null +++ b/.scribe/endpoints.cache/10.yaml @@ -0,0 +1,392 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: sites +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/sites' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all sites.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gaeE86fd1aZP53Vvc6Dhbk4' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/sites' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new site.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + type: + name: type + description: '' + required: true + example: wordpress + type: string + enumValues: + - php + - php-blank + - phpmyadmin + - laravel + - wordpress + exampleWasSpecified: false + nullable: false + custom: [] + domain: + name: domain + description: '' + required: true + example: quo + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + aliases: + name: aliases + description: '' + required: true + example: + - dolorum + type: 'string[]' + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + php_version: + name: php_version + description: 'One of the installed PHP Versions' + required: true + example: '7.4' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + web_directory: + name: web_directory + description: 'Required for PHP and Laravel sites' + required: true + example: public + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + source_control: + name: source_control + description: 'Source control ID, Required for Sites which support source control' + required: true + example: explicabo + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + repository: + name: repository + description: 'Repository, Required for Sites which support source control' + required: true + example: organization/repository + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + branch: + name: branch + description: 'Branch, Required for Sites which support source control' + required: true + example: main + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + composer: + name: composer + description: 'Run composer if site supports composer' + required: true + example: true + type: boolean + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + version: + name: version + description: 'Version, if the site type requires a version like PHPMyAdmin' + required: true + example: 5.2.1 + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + type: wordpress + domain: quo + aliases: + - dolorum + php_version: '7.4' + web_directory: public + source_control: explicabo + repository: organization/repository + branch: main + composer: true + version: 5.2.1 + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer efDd36cab6vZEaV4hkP851g' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/sites/{id}' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a site by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the site.' + required: true + example: 8 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + id: 8 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer bVkf841ava5gE6DPch36Zde' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/sites/{site_id}' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete site.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + site_id: + name: site_id + description: 'The ID of the site.' + required: true + example: 8 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + site_id: 8 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gfVZbEP5Ddah6k13ae6c8v4' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/11.yaml b/.scribe/endpoints.cache/11.yaml new file mode 100644 index 0000000..8ee8bed --- /dev/null +++ b/.scribe/endpoints.cache/11.yaml @@ -0,0 +1,430 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: source-controls +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/source-controls' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":5,"project_id":null,"global":true,"name":"Jaiden Kling","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":6,"project_id":null,"global":true,"name":"Ms. Brianne Bosco","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer PfaEg1eZh66cd5V4v8bD3ak' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/source-controls' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The provider' + required: true + example: bitbucket + type: string + enumValues: + - gitlab + - github + - bitbucket + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the storage provider.' + required: true + example: eos + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: et + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + url: + name: url + description: 'The URL if the provider is Gitlab and it is self-hosted' + required: true + example: 'https://lueilwitz.com/nostrum-et-porro-atque-sint.html' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + username: + name: username + description: 'The username if the provider is Bitbucket' + required: true + example: consectetur + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + password: + name: password + description: 'The password if the provider is Bitbucket' + required: true + example: 'PL.P?{06\ECi0' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: bitbucket + name: eos + token: et + url: 'https://lueilwitz.com/nostrum-et-porro-atque-sint.html' + username: consectetur + password: 'PL.P?{06\ECi0' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":5,"project_id":null,"global":true,"name":"Toby Parker","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer V5Zf3a1ve6d6kP4cbgha8DE' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/source-controls/{sourceControl_id}' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sourceControl_id: + name: sourceControl_id + description: 'The ID of the sourceControl.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + sourceControl_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":5,"project_id":null,"global":true,"name":"Prof. Bartholome Graham IV","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer k1b5hac6veZ36P8gDV4fadE' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{project_id}/source-controls/{sourceControl_id}' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sourceControl_id: + name: sourceControl_id + description: 'The ID of the sourceControl.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + sourceControl_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the storage provider.' + required: true + example: quaerat + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: consectetur + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + url: + name: url + description: 'The URL if the provider is Gitlab and it is self-hosted' + required: true + example: 'http://www.hudson.biz/rerum-voluptatem-debitis-accusamus' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + username: + name: username + description: 'The username if the provider is Bitbucket' + required: true + example: voluptatem + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + password: + name: password + description: 'The password if the provider is Bitbucket' + required: true + example: '\p/el>)3#~E?kI' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + global: + name: global + description: 'Accessible in all projects' + required: true + example: false + type: string + enumValues: + - true + - false + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: quaerat + token: consectetur + url: 'http://www.hudson.biz/rerum-voluptatem-debitis-accusamus' + username: voluptatem + password: '\p/el>)3#~E?kI' + global: false + fileParameters: [] + responses: + - + status: 200 + content: '{"id":5,"project_id":null,"global":true,"name":"Cicero Smitham","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6dkE6h8a5eg3f14acVvbPDZ' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/source-controls/{sourceControl_id}' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sourceControl_id: + name: sourceControl_id + description: 'The ID of the sourceControl.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + sourceControl_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer fb6Zk4EP318eva5hDdcV6ga' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints.cache/12.yaml b/.scribe/endpoints.cache/12.yaml new file mode 100644 index 0000000..3ab9973 --- /dev/null +++ b/.scribe/endpoints.cache/12.yaml @@ -0,0 +1,372 @@ +## Autogenerated by Scribe. DO NOT MODIFY. + +name: storage-providers +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/storage-providers' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":3,"project_id":null,"global":true,"name":"et","provider":"local","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":4,"project_id":null,"global":true,"name":"sed","provider":"local","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 1dbV3vkh6EPD5g48cafeZ6a' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/storage-providers' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)' + required: true + example: quod + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the storage provider.' + required: true + example: commodi + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: ipsum + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + key: + name: key + description: 'The key if provider requires key' + required: true + example: ratione + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + secret: + name: secret + description: 'The secret if provider requires key' + required: true + example: iste + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: quod + name: commodi + token: ipsum + key: ratione + secret: iste + fileParameters: [] + responses: + - + status: 200 + content: '{"id":3,"project_id":null,"global":true,"name":"est","provider":"dropbox","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer abehv36kP4D658VafgdZE1c' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/storage-providers/{storageProvider_id}' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + storageProvider_id: + name: storageProvider_id + description: 'The ID of the storageProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + storageProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":3,"project_id":null,"global":true,"name":"officia","provider":"ftp","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer bda64P5c1gEDe8V3Z6vhkaf' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{project_id}/storage-providers/{storageProvider_id}' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + storageProvider_id: + name: storageProvider_id + description: 'The ID of the storageProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + storageProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the storage provider.' + required: true + example: iusto + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + global: + name: global + description: 'Accessible in all projects' + required: true + example: true + type: string + enumValues: + - true + - false + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: iusto + global: true + fileParameters: [] + responses: + - + status: 200 + content: '{"id":3,"project_id":null,"global":true,"name":"rerum","provider":"ftp","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer aEP35hVakDdf814eZvg66cb' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/storage-providers/{storageProvider_id}' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + storageProvider_id: + name: storageProvider_id + description: 'The ID of the storageProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + storageProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer Dah3PgE5d64fcbe8a16VkvZ' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/00.yaml b/.scribe/endpoints/00.yaml new file mode 100644 index 0000000..5c515a7 --- /dev/null +++ b/.scribe/endpoints/00.yaml @@ -0,0 +1,308 @@ +name: cron-jobs +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all cron jobs.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null},{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6ed1gv5ak6hEPcaV8D3Z4bf' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new cron job.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + command: + name: command + description: '' + required: true + example: qui + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + user: + name: user + description: '' + required: true + example: root + type: string + enumValues: + - root + - vito + exampleWasSpecified: false + nullable: false + custom: [] + frequency: + name: frequency + description: 'Frequency of the cron job.' + required: true + example: '* * * * *' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + command: qui + user: root + frequency: '* * * * *' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer VEfc5h3gva68PkZ46Deabd1' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs/{cronJob_id}' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a cron job by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cronJob_id: + name: cronJob_id + description: 'The ID of the cronJob.' + required: true + example: 5 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + cronJob_id: 5 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"command":"ls -la","user":"root","frequency":"* * * * *","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 614DaP5vZ6edcaVEgfhk83b' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/cron-jobs/{cronJob_id}' + metadata: + groupName: cron-jobs + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete cron job.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cronJob_id: + name: cronJob_id + description: 'The ID of the cronJob.' + required: true + example: 5 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + cronJob_id: 5 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gDV6bZ1dEckvf45P86eaha3' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/01.yaml b/.scribe/endpoints/01.yaml new file mode 100644 index 0000000..709995e --- /dev/null +++ b/.scribe/endpoints/01.yaml @@ -0,0 +1,284 @@ +name: databases +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/databases' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all databases.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"name":"clockman","status":"ready","created_at":null,"updated_at":null},{"id":null,"server_id":null,"name":"wvonrueden","status":"ready","created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer efEV4g86bd5PZac6vak3Dh1' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/databases' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new database.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: '' + required: true + example: nesciunt + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: nesciunt + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"name":"johanna76","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 3E6VD14dvaekbaZfh6Pg8c5' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/databases/{id}' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a database by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the database.' + required: true + example: 6 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + id: 6 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"name":"chloe.huel","status":"ready","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer fb5hVc38e1aDP6ZvkgEda46' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/databases/{database_id}' + metadata: + groupName: databases + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete database.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + database_id: + name: database_id + description: 'The ID of the database.' + required: true + example: 6 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + database_id: 6 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer cPVbhaZkfg5aEv46D183ed6' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/02.yaml b/.scribe/endpoints/02.yaml new file mode 100644 index 0000000..bc2f663 --- /dev/null +++ b/.scribe/endpoints/02.yaml @@ -0,0 +1,390 @@ +name: database-users +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/database-users' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all database users.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"username":"nyasia68","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"username":"madyson20","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer egc5VaDdvabfP6843k61hZE' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/database-users' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new database user.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + username: + name: username + description: '' + required: true + example: dignissimos + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + password: + name: password + description: '' + required: true + example: OK+XEG2) + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + host: + name: host + description: 'Host, if it is a remote user.' + required: true + example: '%' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + username: dignissimos + password: OK+XEG2) + host: '%' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"username":"amya.nitzsche","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 31hgfcvEb6Pkaa48D6dZ5Ve' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a database user by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + databaseUser_id: + name: databaseUser_id + description: 'The ID of the databaseUser.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + databaseUser_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"username":"bergstrom.ericka","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer aDv48631h5af6EdkcVbPZeg' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}/link' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: link + description: 'Link to databases' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + databaseUser_id: + name: databaseUser_id + description: 'The ID of the databaseUser.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + databaseUser_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + databases: + name: databases + description: 'Array of database names to link to the user.' + required: true + example: accusantium + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + databases: accusantium + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"username":"fmurray","databases":[],"host":"%","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer cf8ZPhV1k3d5DaEva46beg6' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}' + metadata: + groupName: database-users + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete database user.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + databaseUser_id: + name: databaseUser_id + description: 'The ID of the databaseUser.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + databaseUser_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer hdEvkbaPVf4cZ65a8631eDg' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/03.yaml b/.scribe/endpoints/03.yaml new file mode 100644 index 0000000..5a756b5 --- /dev/null +++ b/.scribe/endpoints/03.yaml @@ -0,0 +1,332 @@ +name: firewall-rules +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all firewall rules.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":18074,"source":"189.27.156.82","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":41088,"source":"86.177.121.87","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer vhkc4aPa6ZdeV8D3Ef156gb' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new firewall rule.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + type: + name: type + description: '' + required: true + example: allow + type: string + enumValues: + - allow + - deny + exampleWasSpecified: false + nullable: false + custom: [] + protocol: + name: protocol + description: '' + required: true + example: udp + type: string + enumValues: + - tcp + - udp + exampleWasSpecified: false + nullable: false + custom: [] + port: + name: port + description: '' + required: true + example: voluptates + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + source: + name: source + description: '' + required: true + example: saepe + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + mask: + name: mask + description: 'Mask for source IP.' + required: true + example: '0' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + type: allow + protocol: udp + port: voluptates + source: saepe + mask: '0' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":61992,"source":"47.222.76.48","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 1cEb5P66VeDkf8aahg3Zdv4' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules/{firewallRule_id}' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a firewall rule by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + firewallRule_id: + name: firewallRule_id + description: 'The ID of the firewallRule.' + required: true + example: 7 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + firewallRule_id: 7 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"type":"allow","protocol":"tcp","port":43107,"source":"135.73.216.16","mask":24,"note":"test","status":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6VaPhkD5vd1Z8e6E3cba4gf' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/firewall-rules/{firewallRule_id}' + metadata: + groupName: firewall-rules + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete firewall rule.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + firewallRule_id: + name: firewallRule_id + description: 'The ID of the firewallRule.' + required: true + example: 7 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + firewallRule_id: 7 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer v81d5Efch636aVgZebaPkD4' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/04.yaml b/.scribe/endpoints/04.yaml new file mode 100644 index 0000000..6143e7b --- /dev/null +++ b/.scribe/endpoints/04.yaml @@ -0,0 +1,44 @@ +name: general +description: '' +endpoints: + - + httpMethods: + - GET + uri: api/health + metadata: + groupName: general + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: health-check + description: '' + authenticated: false + custom: [] + headers: + Content-Type: application/json + Accept: application/json + urlParameters: [] + cleanUrlParameters: [] + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"success":true,"version":"2.0.0"}' + headers: + cache-control: 'no-cache, private' + content-type: application/json + x-ratelimit-limit: '60' + x-ratelimit-remaining: '59' + access-control-allow-origin: '*' + description: null + custom: [] + responseFields: [] + auth: [] + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/05.yaml b/.scribe/endpoints/05.yaml new file mode 100644 index 0000000..8e1970e --- /dev/null +++ b/.scribe/endpoints/05.yaml @@ -0,0 +1,258 @@ +name: projects +description: '' +endpoints: + - + httpMethods: + - GET + uri: api/projects + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all projects.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: [] + cleanUrlParameters: [] + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":29,"name":"Zachary Lueilwitz","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":30,"name":"Mrs. Kiarra Heller IV","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer eb14DEPv6cdah65VfZgka38' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: api/projects + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: [] + cleanUrlParameters: [] + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the project.' + required: true + example: quos + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: quos + fileParameters: [] + responses: + - + status: 200 + content: '{"id":29,"name":"Hershel Spinka","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer V1E3566Pf4gkvh8dDZabeca' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{id}' + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a project by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + id: + name: id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":29,"name":"Emery Kiehn","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer haD6e36VZbkf4P8aEcvd15g' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{id}' + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: 'Update project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + id: + name: id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the project.' + required: true + example: ut + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: ut + fileParameters: [] + responses: + - + status: 200 + content: '{"id":29,"name":"Mable Prohaska","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer V14kPa5deva8Ebgc36f6hDZ' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}' + metadata: + groupName: projects + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer k1D68d5ePavVZag6h4fb3cE' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/06.yaml b/.scribe/endpoints/06.yaml new file mode 100644 index 0000000..bb1e5a7 --- /dev/null +++ b/.scribe/endpoints/06.yaml @@ -0,0 +1,514 @@ +name: servers +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all servers in a project.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Dorthy Toy","ssh_user":"vito","ip":"172.132.95.155","local_ip":"118.57.197.65","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null},{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Carrie Sporer","ssh_user":"vito","ip":"184.242.162.173","local_ip":"135.244.50.22","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 8VE41PdZcvb6kgafD635ahe' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The server provider type' + required: true + example: et + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_provider: + name: server_provider + description: 'If the provider is not custom, the ID of the server provider profile' + required: true + example: digitalocean + type: string + enumValues: + - custom + - hetzner + - digitalocean + - linode + - vultr + exampleWasSpecified: false + nullable: false + custom: [] + region: + name: region + description: 'Provider region if the provider is not custom' + required: true + example: inventore + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + plan: + name: plan + description: 'Provider plan if the provider is not custom' + required: true + example: atque + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + ip: + name: ip + description: 'SSH IP address if the provider is custom' + required: true + example: quam + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + port: + name: port + description: 'SSH Port if the provider is custom' + required: true + example: nemo + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the server.' + required: true + example: perspiciatis + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + os: + name: os + description: 'The os of the server' + required: true + example: similique + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + type: + name: type + description: 'Server type' + required: true + example: regular + type: string + enumValues: + - regular + - database + exampleWasSpecified: false + nullable: false + custom: [] + webserver: + name: webserver + description: 'Web server' + required: true + example: none + type: string + enumValues: + - none + - nginx + exampleWasSpecified: false + nullable: false + custom: [] + database: + name: database + description: Database + required: true + example: none + type: string + enumValues: + - none + - mysql57 + - mysql80 + - mariadb103 + - mariadb104 + - mariadb103 + - postgresql12 + - postgresql13 + - postgresql14 + - postgresql15 + - postgresql16 + exampleWasSpecified: false + nullable: false + custom: [] + php: + name: php + description: 'PHP version' + required: true + example: '8.1' + type: string + enumValues: + - '7.0' + - '7.1' + - '7.2' + - '7.3' + - '7.4' + - '8.0' + - '8.1' + - '8.2' + - '8.3' + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: et + server_provider: digitalocean + region: inventore + plan: atque + ip: quam + port: nemo + name: perspiciatis + os: similique + type: regular + webserver: none + database: none + php: '8.1' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Flo Beer PhD","ssh_user":"vito","ip":"168.238.14.230","local_ip":"40.232.73.41","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer Z8g36aaV4E1bdcPfehDv65k' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{id}' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a server by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"project_id":null,"user_id":null,"provider_id":null,"name":"Stephany Ankunding","ssh_user":"vito","ip":"145.28.94.46","local_ip":"69.133.44.100","port":22,"os":"ubuntu_22","type":"regular","type_data":null,"provider":"custom","provider_data":null,"public_key":"test","status":"ready","auto_update":null,"available_updates":0,"security_updates":null,"progress":100,"progress_step":null,"updates":null,"last_update_check":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer adD3EfP5hZ4vgbkV861eca6' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/reboot' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: reboot + description: 'Reboot a server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer P3ec6aagD4hbdV5fEk168vZ' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/upgrade' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: upgrade + description: 'Upgrade server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer P34ZV6D1bEegdvac8f5kh6a' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}' + metadata: + groupName: servers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer ha6v5V41afkdPgcZbDEe386' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/07.yaml b/.scribe/endpoints/07.yaml new file mode 100644 index 0000000..d49ccd1 --- /dev/null +++ b/.scribe/endpoints/07.yaml @@ -0,0 +1,370 @@ +name: server-providers +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/server-providers' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":2,"project_id":null,"global":true,"name":"dolor","provider":"digitalocean","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":3,"project_id":null,"global":true,"name":"enim","provider":"digitalocean","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 1a6kb58vEP3fZdVhcea64gD' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/server-providers' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)' + required: true + example: autem + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the server provider.' + required: true + example: enim + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: culpa + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + key: + name: key + description: 'The key if provider requires key' + required: true + example: sit + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + secret: + name: secret + description: 'The secret if provider requires key' + required: true + example: voluptates + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: autem + name: enim + token: culpa + key: sit + secret: voluptates + fileParameters: [] + responses: + - + status: 200 + content: '{"id":2,"project_id":null,"global":true,"name":"eligendi","provider":"aws","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer PD3ZcaVdvgfa5k4be8E6h16' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/server-providers/{serverProvider_id}' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + serverProvider_id: + name: serverProvider_id + description: 'The ID of the serverProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + serverProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":2,"project_id":null,"global":true,"name":"architecto","provider":"digitalocean","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer DP45bg1aEadh8Z6Vke63fcv' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{project_id}/server-providers/{serverProvider_id}' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + serverProvider_id: + name: serverProvider_id + description: 'The ID of the serverProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + serverProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the server provider.' + required: true + example: minus + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + global: + name: global + description: 'Accessible in all projects' + required: true + example: false + type: string + enumValues: + - true + - false + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: minus + global: false + fileParameters: [] + responses: + - + status: 200 + content: '{"id":2,"project_id":null,"global":true,"name":"reiciendis","provider":"hetzner","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer bv1kdegh6fP8V56ZE4acaD3' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/server-providers/{serverProvider_id}' + metadata: + groupName: server-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + serverProvider_id: + name: serverProvider_id + description: 'The ID of the serverProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + serverProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer k6hb43Vf5Z1dv8aaeEDcg6P' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/08.yaml b/.scribe/endpoints/08.yaml new file mode 100644 index 0000000..ab3a743 --- /dev/null +++ b/.scribe/endpoints/08.yaml @@ -0,0 +1,233 @@ +name: ssh-keys +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/ssh-keys' + metadata: + groupName: ssh-keys + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all ssh keys.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"user":null,"name":"Dr. Reanna Braun","created_at":null,"updated_at":null},{"id":null,"user":null,"name":"Norene Fritsch","created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer dV1gcvfZ46Eh8ebaP5Da63k' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/ssh-keys' + metadata: + groupName: ssh-keys + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Deploy ssh key to server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + key_id: + name: key_id + description: 'The ID of the key.' + required: true + example: vero + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'Key name, required if key_id is not provided.' + required: true + example: voluptates + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + public_key: + name: public_key + description: 'Public Key, required if key_id is not provided.' + required: true + example: dolor + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + key_id: vero + name: voluptates + public_key: dolor + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"user":null,"name":"Sophia D''Amore","created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gkadV36a5f8E6vhb14ZceDP' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/ssh-keys/{sshKey_id}' + metadata: + groupName: ssh-keys + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete ssh key from server.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sshKey_id: + name: sshKey_id + description: 'The ID of the sshKey.' + required: true + example: 4 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + sshKey_id: 4 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer PfchD4Zge386abadE5kV61v' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/09.yaml b/.scribe/endpoints/09.yaml new file mode 100644 index 0000000..2596c65 --- /dev/null +++ b/.scribe/endpoints/09.yaml @@ -0,0 +1,576 @@ +name: services +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/services' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all services.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"type":null,"type_data":null,"name":null,"version":null,"unit":null,"status":null,"is_default":null,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"type":null,"type_data":null,"name":null,"version":null,"unit":null,"status":null,"is_default":null,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer h6bDec51ak84ZVafgv3PE6d' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/services/{id}' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a service by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"type":null,"type_data":null,"name":null,"version":null,"unit":null,"status":null,"is_default":null,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer da4V3kfgZ6a86PchevED5b1' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/start' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: start + description: 'Start service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 86fdV5D6gv1E3ekaPZac4hb' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/stop' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: stop + description: 'Stop service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer kPZ563E1Vfgh4cbDad8vae6' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/restart' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: restart + description: 'Restart service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer fd14PaDb58gchv3ZVeaEk66' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/enable' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: enable + description: 'Enable service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer Dv1aVe6hZfkagdE356b4cP8' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}/disable' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: disable + description: 'Disable service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6bdDc4Eah3ZV18kf6Pveag5' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/services/{service_id}' + metadata: + groupName: services + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete service.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + service_id: + name: service_id + description: 'The ID of the service.' + required: true + example: 27 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + service_id: 27 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 36kf84v6bVhE5gdPDeZ1caa' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/10.yaml b/.scribe/endpoints/10.yaml new file mode 100644 index 0000000..86e64e9 --- /dev/null +++ b/.scribe/endpoints/10.yaml @@ -0,0 +1,390 @@ +name: sites +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/sites' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: 'Get all sites.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null},{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gaeE86fd1aZP53Vvc6Dhbk4' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/servers/{server_id}/sites' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: 'Create a new site.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + type: + name: type + description: '' + required: true + example: wordpress + type: string + enumValues: + - php + - php-blank + - phpmyadmin + - laravel + - wordpress + exampleWasSpecified: false + nullable: false + custom: [] + domain: + name: domain + description: '' + required: true + example: quo + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + aliases: + name: aliases + description: '' + required: true + example: + - dolorum + type: 'string[]' + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + php_version: + name: php_version + description: 'One of the installed PHP Versions' + required: true + example: '7.4' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + web_directory: + name: web_directory + description: 'Required for PHP and Laravel sites' + required: true + example: public + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + source_control: + name: source_control + description: 'Source control ID, Required for Sites which support source control' + required: true + example: explicabo + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + repository: + name: repository + description: 'Repository, Required for Sites which support source control' + required: true + example: organization/repository + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + branch: + name: branch + description: 'Branch, Required for Sites which support source control' + required: true + example: main + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + composer: + name: composer + description: 'Run composer if site supports composer' + required: true + example: true + type: boolean + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + version: + name: version + description: 'Version, if the site type requires a version like PHPMyAdmin' + required: true + example: 5.2.1 + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + type: wordpress + domain: quo + aliases: + - dolorum + php_version: '7.4' + web_directory: public + source_control: explicabo + repository: organization/repository + branch: main + composer: true + version: 5.2.1 + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer efDd36cab6vZEaV4hkP851g' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/servers/{server_id}/sites/{id}' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: 'Get a site by ID.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + id: + name: id + description: 'The ID of the site.' + required: true + example: 8 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + id: 8 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":null,"server_id":null,"source_control_id":null,"type":"laravel","type_data":null,"domain":"test.com","aliases":null,"web_directory":"\/","path":"\/home","php_version":"8.2","repository":null,"branch":"main","status":"ready","port":null,"progress":100,"created_at":null,"updated_at":null}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer bVkf841ava5gE6DPch36Zde' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/servers/{server_id}/sites/{site_id}' + metadata: + groupName: sites + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: 'Delete site.' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + server_id: + name: server_id + description: 'The ID of the server.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + site_id: + name: site_id + description: 'The ID of the site.' + required: true + example: 8 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + server_id: 3 + site_id: 8 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer gfVZbEP5Ddah6k13ae6c8v4' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/11.yaml b/.scribe/endpoints/11.yaml new file mode 100644 index 0000000..a2f3c03 --- /dev/null +++ b/.scribe/endpoints/11.yaml @@ -0,0 +1,428 @@ +name: source-controls +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/source-controls' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":5,"project_id":null,"global":true,"name":"Jaiden Kling","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":6,"project_id":null,"global":true,"name":"Ms. Brianne Bosco","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer PfaEg1eZh66cd5V4v8bD3ak' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/source-controls' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The provider' + required: true + example: bitbucket + type: string + enumValues: + - gitlab + - github + - bitbucket + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the storage provider.' + required: true + example: eos + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: et + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + url: + name: url + description: 'The URL if the provider is Gitlab and it is self-hosted' + required: true + example: 'https://lueilwitz.com/nostrum-et-porro-atque-sint.html' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + username: + name: username + description: 'The username if the provider is Bitbucket' + required: true + example: consectetur + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + password: + name: password + description: 'The password if the provider is Bitbucket' + required: true + example: 'PL.P?{06\ECi0' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: bitbucket + name: eos + token: et + url: 'https://lueilwitz.com/nostrum-et-porro-atque-sint.html' + username: consectetur + password: 'PL.P?{06\ECi0' + fileParameters: [] + responses: + - + status: 200 + content: '{"id":5,"project_id":null,"global":true,"name":"Toby Parker","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer V5Zf3a1ve6d6kP4cbgha8DE' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/source-controls/{sourceControl_id}' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sourceControl_id: + name: sourceControl_id + description: 'The ID of the sourceControl.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + sourceControl_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":5,"project_id":null,"global":true,"name":"Prof. Bartholome Graham IV","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer k1b5hac6veZ36P8gDV4fadE' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{project_id}/source-controls/{sourceControl_id}' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sourceControl_id: + name: sourceControl_id + description: 'The ID of the sourceControl.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + sourceControl_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the storage provider.' + required: true + example: quaerat + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: consectetur + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + url: + name: url + description: 'The URL if the provider is Gitlab and it is self-hosted' + required: true + example: 'http://www.hudson.biz/rerum-voluptatem-debitis-accusamus' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + username: + name: username + description: 'The username if the provider is Bitbucket' + required: true + example: voluptatem + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + password: + name: password + description: 'The password if the provider is Bitbucket' + required: true + example: '\p/el>)3#~E?kI' + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + global: + name: global + description: 'Accessible in all projects' + required: true + example: false + type: string + enumValues: + - true + - false + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: quaerat + token: consectetur + url: 'http://www.hudson.biz/rerum-voluptatem-debitis-accusamus' + username: voluptatem + password: '\p/el>)3#~E?kI' + global: false + fileParameters: [] + responses: + - + status: 200 + content: '{"id":5,"project_id":null,"global":true,"name":"Cicero Smitham","provider":"github","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 6dkE6h8a5eg3f14acVvbPDZ' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/source-controls/{sourceControl_id}' + metadata: + groupName: source-controls + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + sourceControl_id: + name: sourceControl_id + description: 'The ID of the sourceControl.' + required: true + example: 3 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + sourceControl_id: 3 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer fb6Zk4EP318eva5hDdcV6ga' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/12.yaml b/.scribe/endpoints/12.yaml new file mode 100644 index 0000000..86b5451 --- /dev/null +++ b/.scribe/endpoints/12.yaml @@ -0,0 +1,370 @@ +name: storage-providers +description: '' +endpoints: + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/storage-providers' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: list + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"data":[{"id":3,"project_id":null,"global":true,"name":"et","provider":"local","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"},{"id":4,"project_id":null,"global":true,"name":"sed","provider":"local","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}],"links":{"first":"\/?page=1","last":"\/?page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"links":[{"url":null,"label":"« Previous","active":false},{"url":"\/?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"path":"\/","per_page":25,"to":2,"total":2}}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer 1dbV3vkh6EPD5g48cafeZ6a' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - POST + uri: 'api/projects/{project_id}/storage-providers' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: create + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + provider: + name: provider + description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)' + required: true + example: quod + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + name: + name: name + description: 'The name of the storage provider.' + required: true + example: commodi + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + token: + name: token + description: 'The token if provider requires api token' + required: true + example: ipsum + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + key: + name: key + description: 'The key if provider requires key' + required: true + example: ratione + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + secret: + name: secret + description: 'The secret if provider requires key' + required: true + example: iste + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + provider: quod + name: commodi + token: ipsum + key: ratione + secret: iste + fileParameters: [] + responses: + - + status: 200 + content: '{"id":3,"project_id":null,"global":true,"name":"est","provider":"dropbox","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer abehv36kP4D658VafgdZE1c' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - GET + uri: 'api/projects/{project_id}/storage-providers/{storageProvider_id}' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: show + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + storageProvider_id: + name: storageProvider_id + description: 'The ID of the storageProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + storageProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 200 + content: '{"id":3,"project_id":null,"global":true,"name":"officia","provider":"ftp","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer bda64P5c1gEDe8V3Z6vhkaf' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - PUT + uri: 'api/projects/{project_id}/storage-providers/{storageProvider_id}' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: update + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + storageProvider_id: + name: storageProvider_id + description: 'The ID of the storageProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + storageProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: + name: + name: name + description: 'The name of the storage provider.' + required: true + example: iusto + type: string + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + global: + name: global + description: 'Accessible in all projects' + required: true + example: true + type: string + enumValues: + - true + - false + exampleWasSpecified: false + nullable: false + custom: [] + cleanBodyParameters: + name: iusto + global: true + fileParameters: [] + responses: + - + status: 200 + content: '{"id":3,"project_id":null,"global":true,"name":"rerum","provider":"ftp","created_at":"2024-11-01T15:40:48.000000Z","updated_at":"2024-11-01T15:40:48.000000Z"}' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer aEP35hVakDdf814eZvg66cb' + controller: null + method: null + route: null + custom: [] + - + httpMethods: + - DELETE + uri: 'api/projects/{project_id}/storage-providers/{storageProvider_id}' + metadata: + groupName: storage-providers + groupDescription: '' + subgroup: '' + subgroupDescription: '' + title: delete + description: '' + authenticated: true + custom: [] + headers: + Authorization: 'Bearer YOUR-API-KEY' + Content-Type: application/json + Accept: application/json + urlParameters: + project_id: + name: project_id + description: 'The ID of the project.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + storageProvider_id: + name: storageProvider_id + description: 'The ID of the storageProvider.' + required: true + example: 1 + type: integer + enumValues: [] + exampleWasSpecified: false + nullable: false + custom: [] + cleanUrlParameters: + project_id: 1 + storageProvider_id: 1 + queryParameters: [] + cleanQueryParameters: [] + bodyParameters: [] + cleanBodyParameters: [] + fileParameters: [] + responses: + - + status: 204 + content: 'null' + headers: [] + description: '' + custom: [] + responseFields: [] + auth: + - headers + - Authorization + - 'Bearer Dah3PgE5d64fcbe8a16VkvZ' + controller: null + method: null + route: null + custom: [] diff --git a/.scribe/endpoints/custom.0.yaml b/.scribe/endpoints/custom.0.yaml new file mode 100644 index 0000000..4b02352 --- /dev/null +++ b/.scribe/endpoints/custom.0.yaml @@ -0,0 +1,53 @@ +# To include an endpoint that isn't a part of your Laravel app (or belongs to a vendor package), +# you can define it in a custom.*.yaml file, like this one. +# Each custom file should contain an array of endpoints. Here's an example: +# See https://scribe.knuckles.wtf/laravel/documenting/custom-endpoints#extra-sorting-groups-in-custom-endpoint-files for more options + +#- httpMethods: +# - POST +# uri: api/doSomething/{param} +# metadata: +# groupName: The group the endpoint belongs to. Can be a new group or an existing group. +# groupDescription: A description for the group. You don't need to set this for every endpoint; once is enough. +# subgroup: You can add a subgroup, too. +# title: Do something +# description: 'This endpoint allows you to do something.' +# authenticated: false +# headers: +# Content-Type: application/json +# Accept: application/json +# urlParameters: +# param: +# name: param +# description: A URL param for no reason. +# required: true +# example: 2 +# type: integer +# queryParameters: +# speed: +# name: speed +# description: How fast the thing should be done. Can be `slow` or `fast`. +# required: false +# example: fast +# type: string +# bodyParameters: +# something: +# name: something +# description: The things we should do. +# required: true +# example: +# - string 1 +# - string 2 +# type: 'string[]' +# responses: +# - status: 200 +# description: 'When the thing was done smoothly.' +# content: # Your response content can be an object, an array, a string or empty. +# { +# "hey": "ho ho ho" +# } +# responseFields: +# hey: +# name: hey +# description: Who knows? +# type: string # This is optional diff --git a/.scribe/intro.md b/.scribe/intro.md new file mode 100644 index 0000000..abb194c --- /dev/null +++ b/.scribe/intro.md @@ -0,0 +1,13 @@ +# Introduction + +VitoDeploy's API documentation. + + + +This documentation aims to provide all the information you need to work with our API. + + + diff --git a/app/Actions/CronJob/CreateCronJob.php b/app/Actions/CronJob/CreateCronJob.php index f7d824c..905221b 100755 --- a/app/Actions/CronJob/CreateCronJob.php +++ b/app/Actions/CronJob/CreateCronJob.php @@ -9,7 +9,7 @@ class CreateCronJob { - public function create(Server $server, array $input): void + public function create(Server $server, array $input): CronJob { $cronJob = new CronJob([ 'server_id' => $server->id, @@ -23,6 +23,8 @@ public function create(Server $server, array $input): void $server->cron()->update($cronJob->user, CronJob::crontab($server, $cronJob->user)); $cronJob->status = CronjobStatus::READY; $cronJob->save(); + + return $cronJob; } public static function rules(array $input): array diff --git a/app/Actions/Database/CreateDatabaseUser.php b/app/Actions/Database/CreateDatabaseUser.php index 97e5132..66cbfc5 100755 --- a/app/Actions/Database/CreateDatabaseUser.php +++ b/app/Actions/Database/CreateDatabaseUser.php @@ -20,7 +20,7 @@ public function create(Server $server, array $input, array $links = []): Databas 'server_id' => $server->id, 'username' => $input['username'], 'password' => $input['password'], - 'host' => isset($input['remote']) && $input['remote'] ? $input['host'] : 'localhost', + 'host' => (isset($input['remote']) && $input['remote']) || isset($input['host']) ? $input['host'] : 'localhost', 'databases' => $links, ]); /** @var Database $databaseHandler */ diff --git a/app/Actions/Database/LinkUser.php b/app/Actions/Database/LinkUser.php index 83e805d..d2a4c3d 100755 --- a/app/Actions/Database/LinkUser.php +++ b/app/Actions/Database/LinkUser.php @@ -13,7 +13,7 @@ class LinkUser /** * @throws ValidationException */ - public function link(DatabaseUser $databaseUser, array $input): void + public function link(DatabaseUser $databaseUser, array $input): DatabaseUser { if (! isset($input['databases']) || ! is_array($input['databases'])) { $input['databases'] = []; @@ -43,6 +43,10 @@ public function link(DatabaseUser $databaseUser, array $input): void ); $databaseUser->save(); + + $databaseUser->refresh(); + + return $databaseUser; } public static function rules(Server $server, array $input): array diff --git a/app/Actions/Server/CreateServer.php b/app/Actions/Server/CreateServer.php index 9aba8c2..20c2173 100755 --- a/app/Actions/Server/CreateServer.php +++ b/app/Actions/Server/CreateServer.php @@ -6,28 +6,28 @@ use App\Enums\ServerProvider; use App\Enums\ServerStatus; use App\Facades\Notifier; +use App\Models\Project; use App\Models\Server; use App\Models\User; use App\Notifications\ServerInstallationFailed; use App\Notifications\ServerInstallationSucceed; use App\ValidationRules\RestrictedIPAddressesRule; use Exception; +use Illuminate\Database\Query\Builder; use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Illuminate\Validation\Rule; +use Illuminate\Validation\ValidationException; use Throwable; class CreateServer { - /** - * @throws Throwable - */ - public function create(User $creator, array $input): Server + public function create(User $creator, Project $project, array $input): Server { $server = new Server([ - 'project_id' => $creator->currentProject->id, + 'project_id' => $project->id, 'user_id' => $creator->id, 'name' => $input['name'], 'ssh_user' => config('core.server_providers_default_user')[$input['provider']][$input['os']], @@ -76,7 +76,9 @@ public function create(User $creator, array $input): Server } catch (Exception $e) { $server->provider()->delete(); DB::rollBack(); - throw $e; + throw ValidationException::withMessages([ + 'provider' => $e->getMessage(), + ]); } } @@ -112,7 +114,7 @@ function () use ($server) { $bus->onConnection('ssh')->dispatch(); } - public static function rules(array $input): array + public static function rules(Project $project, array $input): array { $rules = [ 'provider' => [ @@ -132,15 +134,18 @@ public static function rules(array $input): array ], 'server_provider' => [ Rule::when(function () use ($input) { - return $input['provider'] != ServerProvider::CUSTOM; + return isset($input['provider']) && $input['provider'] != ServerProvider::CUSTOM; }, [ 'required', - 'exists:server_providers,id,user_id,'.auth()->user()->id, + Rule::exists('server_providers', 'id')->where(function (Builder $query) use ($project) { + $query->where('project_id', $project->id) + ->orWhereNull('project_id'); + }), ]), ], 'ip' => [ Rule::when(function () use ($input) { - return $input['provider'] == ServerProvider::CUSTOM; + return isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM; }, [ 'required', new RestrictedIPAddressesRule, @@ -148,7 +153,7 @@ public static function rules(array $input): array ], 'port' => [ Rule::when(function () use ($input) { - return $input['provider'] == ServerProvider::CUSTOM; + return isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM; }, [ 'required', 'numeric', @@ -176,6 +181,7 @@ private static function providerRules(array $input): array { if ( ! isset($input['provider']) || + ! isset($input['server_provider']) || ! in_array($input['provider'], config('core.server_providers')) || $input['provider'] == ServerProvider::CUSTOM ) { diff --git a/app/Actions/ServerProvider/CreateServerProvider.php b/app/Actions/ServerProvider/CreateServerProvider.php index 573bf4d..6b80cef 100644 --- a/app/Actions/ServerProvider/CreateServerProvider.php +++ b/app/Actions/ServerProvider/CreateServerProvider.php @@ -2,6 +2,7 @@ namespace App\Actions\ServerProvider; +use App\Models\Project; use App\Models\ServerProvider; use App\Models\User; use App\ServerProviders\ServerProvider as ServerProviderContract; @@ -14,7 +15,7 @@ class CreateServerProvider /** * @throws ValidationException */ - public function create(User $user, array $input): ServerProvider + public function create(User $user, Project $project, array $input): ServerProvider { $provider = static::getProvider($input['provider']); @@ -33,7 +34,7 @@ public function create(User $user, array $input): ServerProvider $serverProvider->profile = $input['name']; $serverProvider->provider = $input['provider']; $serverProvider->credentials = $provider->credentialData($input); - $serverProvider->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id; + $serverProvider->project_id = isset($input['global']) && $input['global'] ? null : $project->id; $serverProvider->save(); return $serverProvider; @@ -46,9 +47,9 @@ private static function getProvider($name): ServerProviderContract return new $providerClass; } - public static function rules(): array + public static function rules(array $input): array { - return [ + $rules = [ 'name' => [ 'required', ], @@ -58,10 +59,16 @@ public static function rules(): array Rule::notIn('custom'), ], ]; + + return array_merge($rules, static::providerRules($input)); } - public static function providerRules(array $input): array + private static function providerRules(array $input): array { + if (! isset($input['provider'])) { + return []; + } + return static::getProvider($input['provider'])->credentialValidationRules($input); } } diff --git a/app/Actions/ServerProvider/DeleteServerProvider.php b/app/Actions/ServerProvider/DeleteServerProvider.php index 873ddb0..77e4f0e 100644 --- a/app/Actions/ServerProvider/DeleteServerProvider.php +++ b/app/Actions/ServerProvider/DeleteServerProvider.php @@ -3,17 +3,16 @@ namespace App\Actions\ServerProvider; use App\Models\ServerProvider; -use Exception; +use Illuminate\Validation\ValidationException; class DeleteServerProvider { - /** - * @throws Exception - */ public function delete(ServerProvider $serverProvider): void { if ($serverProvider->servers()->exists()) { - throw new Exception('This server provider is being used by a server.'); + throw ValidationException::withMessages([ + 'provider' => 'This server provider is being used by a server.', + ]); } $serverProvider->delete(); diff --git a/app/Actions/ServerProvider/EditServerProvider.php b/app/Actions/ServerProvider/EditServerProvider.php index 476ffcb..82f8947 100644 --- a/app/Actions/ServerProvider/EditServerProvider.php +++ b/app/Actions/ServerProvider/EditServerProvider.php @@ -2,17 +2,19 @@ namespace App\Actions\ServerProvider; +use App\Models\Project; use App\Models\ServerProvider; -use App\Models\User; class EditServerProvider { - public function edit(ServerProvider $serverProvider, User $user, array $input): void + public function edit(ServerProvider $serverProvider, Project $project, array $input): ServerProvider { $serverProvider->profile = $input['name']; - $serverProvider->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id; + $serverProvider->project_id = isset($input['global']) && $input['global'] ? null : $project->id; $serverProvider->save(); + + return $serverProvider; } public static function rules(): array diff --git a/app/Actions/Service/Uninstall.php b/app/Actions/Service/Uninstall.php index 6528647..e516e74 100644 --- a/app/Actions/Service/Uninstall.php +++ b/app/Actions/Service/Uninstall.php @@ -8,6 +8,9 @@ class Uninstall { + /* + * @TODO: Implement the uninstaller for all service handlers + */ public function uninstall(Service $service): void { Validator::make([ diff --git a/app/Actions/Site/CreateSite.php b/app/Actions/Site/CreateSite.php index f8b9e07..f5ec875 100755 --- a/app/Actions/Site/CreateSite.php +++ b/app/Actions/Site/CreateSite.php @@ -19,9 +19,6 @@ class CreateSite { - /** - * @throws SourceControlIsNotConnected - */ public function create(Server $server, array $input): Site { DB::beginTransaction(); @@ -88,13 +85,12 @@ public function create(Server $server, array $input): Site return $site; } catch (Exception $e) { DB::rollBack(); - throw $e; + throw ValidationException::withMessages([ + 'type' => $e->getMessage(), + ]); } } - /** - * @throws ValidationException - */ public static function rules(Server $server, array $input): array { $rules = [ diff --git a/app/Actions/SourceControl/ConnectSourceControl.php b/app/Actions/SourceControl/ConnectSourceControl.php index bfcb8a2..826d291 100644 --- a/app/Actions/SourceControl/ConnectSourceControl.php +++ b/app/Actions/SourceControl/ConnectSourceControl.php @@ -2,6 +2,7 @@ namespace App\Actions\SourceControl; +use App\Models\Project; use App\Models\SourceControl; use App\Models\User; use Illuminate\Support\Arr; @@ -10,13 +11,13 @@ class ConnectSourceControl { - public function connect(User $user, array $input): void + public function connect(User $user, Project $project, array $input): SourceControl { $sourceControl = new SourceControl([ 'provider' => $input['provider'], 'profile' => $input['name'], 'url' => Arr::has($input, 'url') ? $input['url'] : null, - 'project_id' => isset($input['global']) && $input['global'] ? null : $user->current_project_id, + 'project_id' => isset($input['global']) && $input['global'] ? null : $project->id, ]); $sourceControl->provider_data = $sourceControl->provider()->createData($input); @@ -29,6 +30,8 @@ public function connect(User $user, array $input): void } $sourceControl->save(); + + return $sourceControl; } public static function rules(array $input): array diff --git a/app/Actions/SourceControl/DeleteSourceControl.php b/app/Actions/SourceControl/DeleteSourceControl.php index e084056..dfe1c85 100644 --- a/app/Actions/SourceControl/DeleteSourceControl.php +++ b/app/Actions/SourceControl/DeleteSourceControl.php @@ -3,13 +3,16 @@ namespace App\Actions\SourceControl; use App\Models\SourceControl; +use Illuminate\Validation\ValidationException; class DeleteSourceControl { public function delete(SourceControl $sourceControl): void { if ($sourceControl->sites()->exists()) { - throw new \Exception('This source control is being used by a site.'); + throw ValidationException::withMessages([ + 'source_control' => __('This source control is being used by a site.'), + ]); } $sourceControl->delete(); diff --git a/app/Actions/SourceControl/EditSourceControl.php b/app/Actions/SourceControl/EditSourceControl.php index b5eea45..9bde514 100644 --- a/app/Actions/SourceControl/EditSourceControl.php +++ b/app/Actions/SourceControl/EditSourceControl.php @@ -2,59 +2,47 @@ namespace App\Actions\SourceControl; +use App\Models\Project; use App\Models\SourceControl; -use App\Models\User; -use Illuminate\Validation\Rule; use Illuminate\Validation\ValidationException; class EditSourceControl { - public function edit(SourceControl $sourceControl, User $user, array $input): void + public function edit(SourceControl $sourceControl, Project $project, array $input): SourceControl { $sourceControl->profile = $input['name']; $sourceControl->url = $input['url'] ?? null; - $sourceControl->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id; + $sourceControl->project_id = isset($input['global']) && $input['global'] ? null : $project->id; - $sourceControl->provider_data = $sourceControl->provider()->createData($input); + $sourceControl->provider_data = $sourceControl->provider()->editData($input); if (! $sourceControl->provider()->connect()) { throw ValidationException::withMessages([ - 'token' => __('Cannot connect to :provider or invalid token!', ['provider' => $sourceControl->provider] - ), + 'token' => __('Cannot connect to :provider or invalid token!', ['provider' => $sourceControl->provider]), ]); } $sourceControl->save(); + + return $sourceControl; } - public static function rules(array $input): array + public static function rules(SourceControl $sourceControl, array $input): array { $rules = [ 'name' => [ 'required', ], - 'provider' => [ - 'required', - Rule::in(config('core.source_control_providers')), - ], ]; - return array_merge($rules, static::providerRules($input)); + return array_merge($rules, static::providerRules($sourceControl, $input)); } /** * @throws ValidationException */ - private static function providerRules(array $input): array + private static function providerRules(SourceControl $sourceControl, array $input): array { - if (! isset($input['provider'])) { - return []; - } - - $sourceControl = new SourceControl([ - 'provider' => $input['provider'], - ]); - - return $sourceControl->provider()->createRules($input); + return $sourceControl->provider()->editRules($input); } } diff --git a/app/Actions/StorageProvider/CreateStorageProvider.php b/app/Actions/StorageProvider/CreateStorageProvider.php index c451d92..4c55e1b 100644 --- a/app/Actions/StorageProvider/CreateStorageProvider.php +++ b/app/Actions/StorageProvider/CreateStorageProvider.php @@ -2,6 +2,7 @@ namespace App\Actions\StorageProvider; +use App\Models\Project; use App\Models\StorageProvider; use App\Models\User; use Illuminate\Validation\Rule; @@ -12,13 +13,13 @@ class CreateStorageProvider /** * @throws ValidationException */ - public function create(User $user, array $input): void + public function create(User $user, Project $project, array $input): StorageProvider { $storageProvider = new StorageProvider([ 'user_id' => $user->id, 'provider' => $input['provider'], 'profile' => $input['name'], - 'project_id' => isset($input['global']) && $input['global'] ? null : $user->current_project_id, + 'project_id' => isset($input['global']) && $input['global'] ? null : $project->id, ]); $storageProvider->credentials = $storageProvider->provider()->credentialData($input); @@ -36,6 +37,8 @@ public function create(User $user, array $input): void } $storageProvider->save(); + + return $storageProvider; } public static function rules(array $input): array diff --git a/app/Actions/StorageProvider/DeleteStorageProvider.php b/app/Actions/StorageProvider/DeleteStorageProvider.php index d8cd5cf..4cbe72b 100644 --- a/app/Actions/StorageProvider/DeleteStorageProvider.php +++ b/app/Actions/StorageProvider/DeleteStorageProvider.php @@ -3,17 +3,16 @@ namespace App\Actions\StorageProvider; use App\Models\StorageProvider; -use Exception; +use Illuminate\Validation\ValidationException; class DeleteStorageProvider { - /** - * @throws Exception - */ public function delete(StorageProvider $storageProvider): void { if ($storageProvider->backups()->exists()) { - throw new Exception('This storage provider is being used by a backup.'); + throw ValidationException::withMessages([ + 'provider' => __('This storage provider is being used by a backup.'), + ]); } $storageProvider->delete(); diff --git a/app/Actions/StorageProvider/EditStorageProvider.php b/app/Actions/StorageProvider/EditStorageProvider.php index 565bff0..824cdd4 100644 --- a/app/Actions/StorageProvider/EditStorageProvider.php +++ b/app/Actions/StorageProvider/EditStorageProvider.php @@ -2,18 +2,20 @@ namespace App\Actions\StorageProvider; +use App\Models\Project; use App\Models\StorageProvider; -use App\Models\User; use Illuminate\Validation\ValidationException; class EditStorageProvider { - public function edit(StorageProvider $storageProvider, User $user, array $input): void + public function edit(StorageProvider $storageProvider, Project $project, array $input): StorageProvider { $storageProvider->profile = $input['name']; - $storageProvider->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id; + $storageProvider->project_id = isset($input['global']) && $input['global'] ? null : $project->id; $storageProvider->save(); + + return $storageProvider; } /** diff --git a/app/Actions/Tag/AttachTag.php b/app/Actions/Tag/AttachTag.php deleted file mode 100644 index e41fb59..0000000 --- a/app/Actions/Tag/AttachTag.php +++ /dev/null @@ -1,61 +0,0 @@ -validate($input); - - /** @var Server|Site $taggable */ - $taggable = $input['taggable_type']::findOrFail($input['taggable_id']); - - $tag = Tag::query()->where('name', $input['name'])->first(); - if ($tag) { - if (! $taggable->tags->contains($tag->id)) { - $taggable->tags()->attach($tag->id); - } - - return $tag; - } - - $tag = new Tag([ - 'project_id' => $user->currentProject->id, - 'name' => $input['name'], - 'color' => config('core.tag_colors')[array_rand(config('core.tag_colors'))], - ]); - $tag->save(); - - $taggable->tags()->attach($tag->id); - - return $tag; - } - - private function validate(array $input): void - { - Validator::make($input, [ - 'name' => [ - 'required', - ], - 'taggable_id' => [ - 'required', - 'integer', - ], - 'taggable_type' => [ - 'required', - Rule::in(config('core.taggable_types')), - ], - ])->validate(); - } -} diff --git a/app/Actions/Tag/DetachTag.php b/app/Actions/Tag/DetachTag.php deleted file mode 100644 index 789ad40..0000000 --- a/app/Actions/Tag/DetachTag.php +++ /dev/null @@ -1,39 +0,0 @@ -validate($input); - - /** @var Server|Site $taggable */ - $taggable = $input['taggable_type']::findOrFail($input['taggable_id']); - - $taggable->tags()->detach($tag->id); - } - - private function validate(array $input): void - { - Validator::make($input, [ - 'taggable_id' => [ - 'required', - 'integer', - ], - 'taggable_type' => [ - 'required', - Rule::in(config('core.taggable_types')), - ], - ])->validate(); - } -} diff --git a/app/Console/Commands/CreateUserCommand.php b/app/Console/Commands/CreateUserCommand.php index c3bd6ee..bd7c5d9 100644 --- a/app/Console/Commands/CreateUserCommand.php +++ b/app/Console/Commands/CreateUserCommand.php @@ -21,13 +21,15 @@ public function handle(): void return; } - User::query()->create([ + $user = User::query()->create([ 'name' => $this->argument('name'), 'email' => $this->argument('email'), 'password' => bcrypt($this->argument('password')), 'role' => $this->option('role'), ]); + $user->createDefaultProject(); + $this->info('User created!'); } } diff --git a/app/Enums/Database.php b/app/Enums/Database.php index 351ae69..6c16e05 100644 --- a/app/Enums/Database.php +++ b/app/Enums/Database.php @@ -2,8 +2,12 @@ namespace App\Enums; +use App\Traits\Enum; + final class Database { + use Enum; + const NONE = 'none'; const MYSQL57 = 'mysql57'; diff --git a/app/Enums/PHP.php b/app/Enums/PHP.php new file mode 100644 index 0000000..6201c86 --- /dev/null +++ b/app/Enums/PHP.php @@ -0,0 +1,30 @@ +, \Psr\Log\LogLevel::*> + * @var array, \Psr\Log\LogLevel::*> */ protected $levels = [ // @@ -19,7 +21,7 @@ class Handler extends ExceptionHandler /** * A list of the exception types that are not reported. * - * @var array> + * @var array> */ protected $dontReport = [ // @@ -45,4 +47,13 @@ public function register(): void // }); } + + public function render($request, Throwable $e): Response + { + if ($e instanceof ModelNotFoundException) { + abort(404, class_basename($e->getModel()).' not found.'); + } + + return parent::render($request, $e); + } } diff --git a/app/Http/Controllers/API/AgentController.php b/app/Http/Controllers/API/AgentController.php index 2271d8c..9dcde54 100644 --- a/app/Http/Controllers/API/AgentController.php +++ b/app/Http/Controllers/API/AgentController.php @@ -7,9 +7,11 @@ use App\Models\Service; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Spatie\RouteAttributes\Attributes\Post; class AgentController extends Controller { + #[Post('api/servers/{server}/agent/{id}', name: 'api.servers.agent')] public function __invoke(Request $request, Server $server, int $id): JsonResponse { $validated = $this->validate($request, [ diff --git a/app/Http/Controllers/API/CronJobController.php b/app/Http/Controllers/API/CronJobController.php new file mode 100644 index 0000000..cdb3fbc --- /dev/null +++ b/app/Http/Controllers/API/CronJobController.php @@ -0,0 +1,97 @@ +authorize('viewAny', [CronJob::class, $server]); + + $this->validateRoute($project, $server); + + return CronJobResource::collection($server->cronJobs()->simplePaginate(25)); + } + + #[Post('/', name: 'api.projects.servers.cron-jobs.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Create a new cron job.')] + #[BodyParam(name: 'command', required: true)] + #[BodyParam(name: 'user', required: true, enum: ['root', 'vito'])] + #[BodyParam(name: 'frequency', description: 'Frequency of the cron job.', required: true, example: '* * * * *')] + #[ResponseFromApiResource(CronJobResource::class, CronJob::class)] + public function create(Request $request, Project $project, Server $server): CronJobResource + { + $this->authorize('create', [CronJob::class, $server]); + + $this->validateRoute($project, $server); + + $this->validate($request, CreateCronJob::rules($request->all())); + + $cronJob = app(CreateCronJob::class)->create($server, $request->all()); + + return new CronJobResource($cronJob); + } + + #[Get('{cronJob}', name: 'api.projects.servers.cron-jobs.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a cron job by ID.')] + #[ResponseFromApiResource(CronJobResource::class, CronJob::class)] + public function show(Project $project, Server $server, CronJob $cronJob): CronJobResource + { + $this->authorize('view', [$cronJob, $server]); + + $this->validateRoute($project, $server, $cronJob); + + return new CronJobResource($cronJob); + } + + #[Delete('{cronJob}', name: 'api.projects.servers.cron-jobs.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete cron job.')] + #[Response(status: 204)] + public function delete(Project $project, Server $server, CronJob $cronJob) + { + $this->authorize('delete', [$cronJob, $server]); + + $this->validateRoute($project, $server, $cronJob); + + app(DeleteCronJob::class)->delete($server, $cronJob); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server, ?CronJob $cronJob = null): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + + if ($cronJob && $cronJob->server_id !== $server->id) { + abort(404, 'Firewall rule not found in server'); + } + } +} diff --git a/app/Http/Controllers/API/DatabaseController.php b/app/Http/Controllers/API/DatabaseController.php new file mode 100644 index 0000000..e1a6593 --- /dev/null +++ b/app/Http/Controllers/API/DatabaseController.php @@ -0,0 +1,94 @@ +authorize('viewAny', [Database::class, $server]); + + $this->validateRoute($project, $server); + + return DatabaseResource::collection($server->databases()->simplePaginate(25)); + } + + #[Post('/', name: 'api.projects.servers.databases.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Create a new database.')] + #[BodyParam(name: 'name', required: true)] + #[ResponseFromApiResource(DatabaseResource::class, Database::class)] + public function create(Request $request, Project $project, Server $server): DatabaseResource + { + $this->authorize('create', [Database::class, $server]); + + $this->validateRoute($project, $server); + + $this->validate($request, CreateDatabase::rules($server, $request->input())); + + $database = app(CreateDatabase::class)->create($server, $request->all()); + + return new DatabaseResource($database); + } + + #[Get('{database}', name: 'api.projects.servers.databases.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a database by ID.')] + #[ResponseFromApiResource(DatabaseResource::class, Database::class)] + public function show(Project $project, Server $server, Database $database): DatabaseResource + { + $this->authorize('view', [$database, $server]); + + $this->validateRoute($project, $server, $database); + + return new DatabaseResource($database); + } + + #[Delete('{database}', name: 'api.projects.servers.databases.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete database.')] + #[Response(status: 204)] + public function delete(Project $project, Server $server, Database $database) + { + $this->authorize('delete', [$database, $server]); + + $this->validateRoute($project, $server, $database); + + $database->delete(); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server, ?Database $database = null): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + + if ($database && $database->server_id !== $server->id) { + abort(404, 'Database not found in server'); + } + } +} diff --git a/app/Http/Controllers/API/DatabaseUserController.php b/app/Http/Controllers/API/DatabaseUserController.php new file mode 100644 index 0000000..0ed3c3d --- /dev/null +++ b/app/Http/Controllers/API/DatabaseUserController.php @@ -0,0 +1,114 @@ +authorize('viewAny', [DatabaseUser::class, $server]); + + $this->validateRoute($project, $server); + + return DatabaseUserResource::collection($server->databaseUsers()->simplePaginate(25)); + } + + #[Post('/', name: 'api.projects.servers.database-users.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Create a new database user.')] + #[BodyParam(name: 'username', required: true)] + #[BodyParam(name: 'password', required: true)] + #[BodyParam(name: 'host', description: 'Host, if it is a remote user.', example: '%')] + #[ResponseFromApiResource(DatabaseUserResource::class, DatabaseUser::class)] + public function create(Request $request, Project $project, Server $server): DatabaseUserResource + { + $this->authorize('create', [DatabaseUser::class, $server]); + + $this->validateRoute($project, $server); + + $this->validate($request, CreateDatabaseUser::rules($server, $request->input())); + + $databaseUser = app(CreateDatabaseUser::class)->create($server, $request->all()); + + return new DatabaseUserResource($databaseUser); + } + + #[Get('{databaseUser}', name: 'api.projects.servers.database-users.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a database user by ID.')] + #[ResponseFromApiResource(DatabaseUserResource::class, DatabaseUser::class)] + public function show(Project $project, Server $server, DatabaseUser $databaseUser): DatabaseUserResource + { + $this->authorize('view', [$databaseUser, $server]); + + $this->validateRoute($project, $server, $databaseUser); + + return new DatabaseUserResource($databaseUser); + } + + #[Post('{databaseUser}/link', name: 'api.projects.servers.database-users.link', middleware: 'ability:write')] + #[Endpoint(title: 'link', description: 'Link to databases')] + #[BodyParam(name: 'databases', description: 'Array of database names to link to the user.', required: true)] + #[ResponseFromApiResource(DatabaseUserResource::class, DatabaseUser::class)] + public function link(Request $request, Project $project, Server $server, DatabaseUser $databaseUser): DatabaseUserResource + { + $this->authorize('update', [$databaseUser, $server]); + + $this->validateRoute($project, $server, $databaseUser); + + $this->validate($request, LinkUser::rules($server, $request->all())); + + $databaseUser = app(LinkUser::class)->link($databaseUser, $request->all()); + + return new DatabaseUserResource($databaseUser); + } + + #[Delete('{databaseUser}', name: 'api.projects.servers.database-users.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete database user.')] + #[Response(status: 204)] + public function delete(Project $project, Server $server, DatabaseUser $databaseUser) + { + $this->authorize('delete', [$databaseUser, $server]); + + $this->validateRoute($project, $server, $databaseUser); + + $databaseUser->delete(); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server, ?DatabaseUser $databaseUser = null): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + + if ($databaseUser && $databaseUser->server_id !== $server->id) { + abort(404, 'Database user not found in server'); + } + } +} diff --git a/app/Http/Controllers/API/FirewallRuleController.php b/app/Http/Controllers/API/FirewallRuleController.php new file mode 100644 index 0000000..e4cfd58 --- /dev/null +++ b/app/Http/Controllers/API/FirewallRuleController.php @@ -0,0 +1,99 @@ +authorize('viewAny', [FirewallRule::class, $server]); + + $this->validateRoute($project, $server); + + return FirewallRuleResource::collection($server->firewallRules()->simplePaginate(25)); + } + + #[Post('/', name: 'api.projects.servers.firewall-rules.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Create a new firewall rule.')] + #[BodyParam(name: 'type', required: true, enum: ['allow', 'deny'])] + #[BodyParam(name: 'protocol', required: true, enum: ['tcp', 'udp'])] + #[BodyParam(name: 'port', required: true)] + #[BodyParam(name: 'source', required: true)] + #[BodyParam(name: 'mask', description: 'Mask for source IP.', example: '0')] + #[ResponseFromApiResource(FirewallRuleResource::class, FirewallRule::class)] + public function create(Request $request, Project $project, Server $server): FirewallRuleResource + { + $this->authorize('create', [FirewallRule::class, $server]); + + $this->validateRoute($project, $server); + + $this->validate($request, CreateRule::rules()); + + $firewallRule = app(CreateRule::class)->create($server, $request->all()); + + return new FirewallRuleResource($firewallRule); + } + + #[Get('{firewallRule}', name: 'api.projects.servers.firewall-rules.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a firewall rule by ID.')] + #[ResponseFromApiResource(FirewallRuleResource::class, FirewallRule::class)] + public function show(Project $project, Server $server, FirewallRule $firewallRule): FirewallRuleResource + { + $this->authorize('view', [$firewallRule, $server]); + + $this->validateRoute($project, $server, $firewallRule); + + return new FirewallRuleResource($firewallRule); + } + + #[Delete('{firewallRule}', name: 'api.projects.servers.firewall-rules.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete firewall rule.')] + #[Response(status: 204)] + public function delete(Project $project, Server $server, FirewallRule $firewallRule) + { + $this->authorize('delete', [$firewallRule, $server]); + + $this->validateRoute($project, $server, $firewallRule); + + app(DeleteRule::class)->delete($server, $firewallRule); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server, ?FirewallRule $firewallRule = null): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + + if ($firewallRule && $firewallRule->server_id !== $server->id) { + abort(404, 'Firewall rule not found in server'); + } + } +} diff --git a/app/Http/Controllers/API/GitHookController.php b/app/Http/Controllers/API/GitHookController.php index 9678db7..5d254da 100644 --- a/app/Http/Controllers/API/GitHookController.php +++ b/app/Http/Controllers/API/GitHookController.php @@ -11,10 +11,12 @@ use App\Notifications\SourceControlDisconnected; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; +use Spatie\RouteAttributes\Attributes\Any; use Throwable; class GitHookController extends Controller { + #[Any('api/git-hooks', name: 'api.git-hooks')] public function __invoke(Request $request) { if (! $request->input('secret')) { diff --git a/app/Http/Controllers/API/HealthController.php b/app/Http/Controllers/API/HealthController.php index 37e8832..ac1f570 100644 --- a/app/Http/Controllers/API/HealthController.php +++ b/app/Http/Controllers/API/HealthController.php @@ -3,9 +3,17 @@ namespace App\Http\Controllers\API; use App\Http\Controllers\Controller; +use Knuckles\Scribe\Attributes\Endpoint; +use Knuckles\Scribe\Attributes\Group; +use Knuckles\Scribe\Attributes\Unauthenticated; +use Spatie\RouteAttributes\Attributes\Get; +#[Group(name: 'general')] class HealthController extends Controller { + #[Get('api/health', name: 'api.health')] + #[Unauthenticated] + #[Endpoint(title: 'health-check')] public function __invoke() { return response()->json([ diff --git a/app/Http/Controllers/API/ProjectController.php b/app/Http/Controllers/API/ProjectController.php new file mode 100644 index 0000000..99666fb --- /dev/null +++ b/app/Http/Controllers/API/ProjectController.php @@ -0,0 +1,89 @@ +authorize('viewAny', Project::class); + + return ProjectResource::collection(Project::all()); + } + + #[Post('api/projects', name: 'api.projects.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Create a new project.')] + #[BodyParam(name: 'name', description: 'The name of the project.', required: true)] + #[ResponseFromApiResource(ProjectResource::class, Project::class)] + public function create(Request $request): ProjectResource + { + $this->authorize('create', Project::class); + + $this->validate($request, CreateProject::rules()); + + $project = app(CreateProject::class)->create(auth()->user(), $request->all()); + + return new ProjectResource($project); + } + + #[Get('api/projects/{project}', name: 'api.projects.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a project by ID.')] + #[ResponseFromApiResource(ProjectResource::class, Project::class)] + public function show(Project $project): ProjectResource + { + $this->authorize('view', $project); + + return new ProjectResource($project); + } + + #[Put('api/projects/{project}', name: 'api.projects.update', middleware: 'ability:write')] + #[Endpoint(title: 'update', description: 'Update project.')] + #[BodyParam(name: 'name', description: 'The name of the project.', required: true)] + #[ResponseFromApiResource(ProjectResource::class, Project::class)] + public function update(Request $request, Project $project): ProjectResource + { + $this->authorize('update', $project); + + $this->validate($request, UpdateProject::rules($project)); + + $project = app(UpdateProject::class)->update($project, $request->all()); + + return new ProjectResource($project); + } + + #[Delete('api/projects/{project}', name: 'api.projects.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete project.')] + #[\Knuckles\Scribe\Attributes\Response(status: 204)] + public function delete(Project $project): Response + { + $this->authorize('delete', $project); + + app(DeleteProject::class)->delete(auth()->user(), $project); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/API/ServerController.php b/app/Http/Controllers/API/ServerController.php new file mode 100644 index 0000000..6dd4e3c --- /dev/null +++ b/app/Http/Controllers/API/ServerController.php @@ -0,0 +1,131 @@ +authorize('viewAny', [Server::class, $project]); + + return ServerResource::collection($project->servers()->simplePaginate(25)); + } + + #[Post('/', name: 'api.projects.servers.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Create a new server.')] + #[BodyParam(name: 'provider', description: 'The server provider type', required: true)] + #[BodyParam(name: 'server_provider', description: 'If the provider is not custom, the ID of the server provider profile', enum: [ServerProvider::CUSTOM, ServerProvider::HETZNER, ServerProvider::DIGITALOCEAN, ServerProvider::LINODE, ServerProvider::VULTR])] + #[BodyParam(name: 'region', description: 'Provider region if the provider is not custom')] + #[BodyParam(name: 'plan', description: 'Provider plan if the provider is not custom')] + #[BodyParam(name: 'ip', description: 'SSH IP address if the provider is custom')] + #[BodyParam(name: 'port', description: 'SSH Port if the provider is custom')] + #[BodyParam(name: 'name', description: 'The name of the server.', required: true)] + #[BodyParam(name: 'os', description: 'The os of the server', required: true)] + #[BodyParam(name: 'type', description: 'Server type', required: true, enum: [ServerType::REGULAR, ServerType::DATABASE])] + #[BodyParam(name: 'webserver', description: 'Web server', required: true, enum: [Webserver::NONE, Webserver::NGINX])] + #[BodyParam(name: 'database', description: 'Database', required: true, enum: [Database::NONE, Database::MYSQL57, Database::MYSQL80, Database::MARIADB103, Database::MARIADB104, Database::MARIADB103, Database::POSTGRESQL12, Database::POSTGRESQL13, Database::POSTGRESQL14, Database::POSTGRESQL15, Database::POSTGRESQL16], )] + #[BodyParam(name: 'php', description: 'PHP version', required: true, enum: [PHP::V70, PHP::V71, PHP::V72, PHP::V73, PHP::V74, PHP::V80, PHP::V81, PHP::V82, PHP::V83])] + #[ResponseFromApiResource(ServerResource::class, Server::class)] + public function create(Request $request, Project $project): ServerResource + { + $this->authorize('create', [Server::class, $project]); + + $this->validate($request, CreateServer::rules($project, $request->input())); + + $server = app(CreateServer::class)->create(auth()->user(), $project, $request->all()); + + return new ServerResource($server); + } + + #[Get('{server}', name: 'api.projects.servers.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a server by ID.')] + #[ResponseFromApiResource(ServerResource::class, Server::class)] + public function show(Project $project, Server $server): ServerResource + { + $this->authorize('view', [$server, $project]); + + $this->validateRoute($project, $server); + + return new ServerResource($server); + } + + #[Post('{server}/reboot', name: 'api.projects.servers.reboot', middleware: 'ability:write')] + #[Endpoint(title: 'reboot', description: 'Reboot a server.')] + #[Response(status: 204)] + public function reboot(Project $project, Server $server) + { + $this->authorize('update', [$server, $project]); + + $this->validateRoute($project, $server); + + app(RebootServer::class)->reboot($server); + + return response()->noContent(); + } + + #[Post('{server}/upgrade', name: 'api.projects.servers.upgrade', middleware: 'ability:write')] + #[Endpoint(title: 'upgrade', description: 'Upgrade server.')] + #[Response(status: 204)] + public function upgrade(Project $project, Server $server) + { + $this->authorize('update', [$server, $project]); + + $this->validateRoute($project, $server); + + app(Update::class)->update($server); + + return response()->noContent(); + } + + #[Delete('{server}', name: 'api.projects.servers.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete server.')] + #[Response(status: 204)] + public function delete(Project $project, Server $server) + { + $this->authorize('delete', [$server, $project]); + + $this->validateRoute($project, $server); + + $server->delete(); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + } +} diff --git a/app/Http/Controllers/API/ServerProviderController.php b/app/Http/Controllers/API/ServerProviderController.php new file mode 100644 index 0000000..869dc58 --- /dev/null +++ b/app/Http/Controllers/API/ServerProviderController.php @@ -0,0 +1,116 @@ +authorize('viewAny', ServerProvider::class); + + $serverProviders = ServerProvider::getByProjectId($project->id)->simplePaginate(25); + + return ServerProviderResource::collection($serverProviders); + } + + #[Post('/', name: 'api.projects.server-providers.create', middleware: 'ability:write')] + #[Endpoint(title: 'create')] + #[BodyParam(name: 'provider', description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)', required: true)] + #[BodyParam(name: 'name', description: 'The name of the server provider.', required: true)] + #[BodyParam(name: 'token', description: 'The token if provider requires api token')] + #[BodyParam(name: 'key', description: 'The key if provider requires key')] + #[BodyParam(name: 'secret', description: 'The secret if provider requires key')] + #[ResponseFromApiResource(ServerProviderResource::class, ServerProvider::class)] + public function create(Request $request, Project $project): ServerProviderResource + { + $this->authorize('create', ServerProvider::class); + + $this->validate($request, CreateServerProvider::rules($request->all())); + + $serverProvider = app(CreateServerProvider::class)->create(auth()->user(), $project, $request->all()); + + return new ServerProviderResource($serverProvider); + } + + #[Get('{serverProvider}', name: 'api.projects.server-providers.show', middleware: 'ability:read')] + #[Endpoint(title: 'show')] + #[ResponseFromApiResource(ServerProviderResource::class, ServerProvider::class)] + public function show(Project $project, ServerProvider $serverProvider) + { + $this->authorize('view', $serverProvider); + + $this->validateRoute($project, $serverProvider); + + return new ServerProviderResource($serverProvider); + } + + #[Put('{serverProvider}', name: 'api.projects.server-providers.update', middleware: 'ability:write')] + #[Endpoint(title: 'update')] + #[BodyParam(name: 'name', description: 'The name of the server provider.', required: true)] + #[BodyParam(name: 'global', description: 'Accessible in all projects', enum: [true, false])] + #[ResponseFromApiResource(ServerProviderResource::class, ServerProvider::class)] + public function update(Request $request, Project $project, ServerProvider $serverProvider) + { + $this->authorize('update', $serverProvider); + + $this->validateRoute($project, $serverProvider); + + $this->validate($request, EditServerProvider::rules()); + + $serverProvider = app(EditServerProvider::class)->edit($serverProvider, $project, $request->all()); + + return new ServerProviderResource($serverProvider); + } + + #[Delete('{serverProvider}', name: 'api.projects.server-providers.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete')] + #[Response(status: 204)] + public function delete(Project $project, ServerProvider $serverProvider) + { + $this->authorize('delete', $serverProvider); + + $this->validateRoute($project, $serverProvider); + + app(DeleteServerProvider::class)->delete($serverProvider); + + return response()->noContent(); + } + + private function validateRoute(Project $project, ServerProvider $serverProvider): void + { + if (! $serverProvider->project_id) { + return; + } + + if ($project->id !== $serverProvider->project_id) { + abort(404, 'Server provider not found in project'); + } + } +} diff --git a/app/Http/Controllers/API/ServerSSHKeyController.php b/app/Http/Controllers/API/ServerSSHKeyController.php new file mode 100644 index 0000000..97a5219 --- /dev/null +++ b/app/Http/Controllers/API/ServerSSHKeyController.php @@ -0,0 +1,92 @@ +authorize('viewAnyServer', [SshKey::class, $server]); + + $this->validateRoute($project, $server); + + return SshKeyResource::collection($server->sshKeys()->simplePaginate(25)); + } + + #[Post('/', name: 'api.projects.servers.ssh-keys.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Deploy ssh key to server.')] + #[BodyParam(name: 'key_id', description: 'The ID of the key.')] + #[BodyParam(name: 'name', description: 'Key name, required if key_id is not provided.')] + #[BodyParam(name: 'public_key', description: 'Public Key, required if key_id is not provided.')] + #[ResponseFromApiResource(SshKeyResource::class, SshKey::class)] + public function create(Request $request, Project $project, Server $server): SshKeyResource + { + $this->authorize('create', [SshKey::class, $server]); + + $this->validateRoute($project, $server); + + $sshKey = null; + if ($request->has('key_id')) { + $this->validate($request, DeployKeyToServer::rules($request->user(), $server)); + + $sshKey = $request->user()->sshKeys()->findOrFail($request->key_id); + } + + if (! $sshKey) { + $this->validate($request, CreateSshKey::rules()); + $sshKey = app(CreateSshKey::class)->create($request->user(), $request->all()); + } + + app(DeployKeyToServer::class)->deploy($server, ['key_id' => $sshKey->id]); + + return new SshKeyResource($sshKey); + } + + #[Delete('{sshKey}', name: 'api.projects.servers.ssh-keys.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete ssh key from server.')] + #[Response(status: 204)] + public function delete(Project $project, Server $server, SshKey $sshKey) + { + $this->authorize('delete', [$sshKey, $server]); + + $this->validateRoute($project, $server); + + app(DeleteKeyFromServer::class)->delete($server, $sshKey); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + } +} diff --git a/app/Http/Controllers/API/ServiceController.php b/app/Http/Controllers/API/ServiceController.php new file mode 100644 index 0000000..6a9601e --- /dev/null +++ b/app/Http/Controllers/API/ServiceController.php @@ -0,0 +1,146 @@ +authorize('viewAny', [Service::class, $server]); + + $this->validateRoute($project, $server); + + return ServiceResource::collection($server->services()->simplePaginate(25)); + } + + #[Get('{service}', name: 'api.projects.servers.services.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a service by ID.')] + #[ResponseFromApiResource(ServiceResource::class, Service::class)] + public function show(Project $project, Server $server, Service $service): ServiceResource + { + $this->authorize('view', [$service, $server]); + + $this->validateRoute($project, $server, $service); + + return new ServiceResource($service); + } + + #[Post('{service}/start', name: 'api.projects.servers.services.start', middleware: 'ability:write')] + #[Endpoint(title: 'start', description: 'Start service.')] + #[Response(status: 204)] + public function start(Project $project, Server $server, Service $service): \Illuminate\Http\Response + { + $this->authorize('update', [$service, $server]); + + $this->validateRoute($project, $server, $service); + + app(Manage::class)->start($service); + + return response()->noContent(); + } + + #[Post('{service}/stop', name: 'api.projects.servers.services.stop', middleware: 'ability:write')] + #[Endpoint(title: 'stop', description: 'Stop service.')] + #[Response(status: 204)] + public function stop(Project $project, Server $server, Service $service): \Illuminate\Http\Response + { + $this->authorize('update', [$service, $server]); + + $this->validateRoute($project, $server, $service); + + app(Manage::class)->stop($service); + + return response()->noContent(); + } + + #[Post('{service}/restart', name: 'api.projects.servers.services.restart', middleware: 'ability:write')] + #[Endpoint(title: 'restart', description: 'Restart service.')] + #[Response(status: 204)] + public function restart(Project $project, Server $server, Service $service): \Illuminate\Http\Response + { + $this->authorize('update', [$service, $server]); + + $this->validateRoute($project, $server, $service); + + app(Manage::class)->restart($service); + + return response()->noContent(); + } + + #[Post('{service}/enable', name: 'api.projects.servers.services.enable', middleware: 'ability:write')] + #[Endpoint(title: 'enable', description: 'Enable service.')] + #[Response(status: 204)] + public function enable(Project $project, Server $server, Service $service): \Illuminate\Http\Response + { + $this->authorize('update', [$service, $server]); + + $this->validateRoute($project, $server, $service); + + app(Manage::class)->enable($service); + + return response()->noContent(); + } + + #[Post('{service}/disable', name: 'api.projects.servers.services.disable', middleware: 'ability:write')] + #[Endpoint(title: 'disable', description: 'Disable service.')] + #[Response(status: 204)] + public function disable(Project $project, Server $server, Service $service): \Illuminate\Http\Response + { + $this->authorize('update', [$service, $server]); + + $this->validateRoute($project, $server, $service); + + app(Manage::class)->disable($service); + + return response()->noContent(); + } + + #[Delete('{service}', name: 'api.projects.servers.services.uninstall', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete service.')] + #[Response(status: 204)] + public function uninstall(Project $project, Server $server, Service $service): \Illuminate\Http\Response + { + $this->authorize('delete', [$service, $server]); + + $this->validateRoute($project, $server, $service); + + app(Uninstall::class)->uninstall($service); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server, ?Service $service = null): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + + if ($service && $service->server_id !== $server->id) { + abort(404, 'Service not found in server'); + } + } +} diff --git a/app/Http/Controllers/API/SiteController.php b/app/Http/Controllers/API/SiteController.php new file mode 100644 index 0000000..d872ba1 --- /dev/null +++ b/app/Http/Controllers/API/SiteController.php @@ -0,0 +1,105 @@ +authorize('viewAny', [Site::class, $server]); + + $this->validateRoute($project, $server); + + return SiteResource::collection($server->sites()->simplePaginate(25)); + } + + #[Post('/', name: 'api.projects.servers.sites.create', middleware: 'ability:write')] + #[Endpoint(title: 'create', description: 'Create a new site.')] + #[BodyParam(name: 'type', required: true, enum: [SiteType::PHP, SiteType::PHP_BLANK, SiteType::PHPMYADMIN, SiteType::LARAVEL, SiteType::WORDPRESS])] + #[BodyParam(name: 'domain', required: true)] + #[BodyParam(name: 'aliases', type: 'array')] + #[BodyParam(name: 'php_version', description: 'One of the installed PHP Versions', required: true, example: '7.4')] + #[BodyParam(name: 'web_directory', description: 'Required for PHP and Laravel sites', example: 'public')] + #[BodyParam(name: 'source_control', description: 'Source control ID, Required for Sites which support source control')] + #[BodyParam(name: 'repository', description: 'Repository, Required for Sites which support source control', example: 'organization/repository')] + #[BodyParam(name: 'branch', description: 'Branch, Required for Sites which support source control', example: 'main')] + #[BodyParam(name: 'composer', type: 'boolean', description: 'Run composer if site supports composer', example: true)] + #[BodyParam(name: 'version', description: 'Version, if the site type requires a version like PHPMyAdmin', example: '5.2.1')] + #[ResponseFromApiResource(SiteResource::class, Site::class)] + public function create(Request $request, Project $project, Server $server): SiteResource + { + $this->authorize('create', [Site::class, $server]); + + $this->validateRoute($project, $server); + + $this->validate($request, CreateSite::rules($server, $request->input())); + + $site = app(CreateSite::class)->create($server, $request->all()); + + return new SiteResource($site); + } + + #[Get('{site}', name: 'api.projects.servers.sites.show', middleware: 'ability:read')] + #[Endpoint(title: 'show', description: 'Get a site by ID.')] + #[ResponseFromApiResource(SiteResource::class, Site::class)] + public function show(Project $project, Server $server, Site $site): ServerResource + { + $this->authorize('view', [$site, $server]); + + $this->validateRoute($project, $server, $site); + + return new ServerResource($server); + } + + #[Delete('{site}', name: 'api.projects.servers.sites.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete', description: 'Delete site.')] + #[Response(status: 204)] + public function delete(Project $project, Server $server, Site $site) + { + $this->authorize('delete', [$site, $server]); + + $this->validateRoute($project, $server, $site); + + $site->delete(); + + return response()->noContent(); + } + + private function validateRoute(Project $project, Server $server, ?Site $site = null): void + { + if ($project->id !== $server->project_id) { + abort(404, 'Server not found in project'); + } + + if ($site && $site->server_id !== $server->id) { + abort(404, 'Site not found in server'); + } + } +} diff --git a/app/Http/Controllers/API/SourceControlController.php b/app/Http/Controllers/API/SourceControlController.php new file mode 100644 index 0000000..5db9345 --- /dev/null +++ b/app/Http/Controllers/API/SourceControlController.php @@ -0,0 +1,121 @@ +authorize('viewAny', SourceControl::class); + + $sourceControls = SourceControl::getByProjectId($project->id)->simplePaginate(25); + + return SourceControlResource::collection($sourceControls); + } + + #[Post('/', name: 'api.projects.source-controls.create', middleware: 'ability:write')] + #[Endpoint(title: 'create')] + #[BodyParam(name: 'provider', description: 'The provider', required: true, enum: [\App\Enums\SourceControl::GITLAB, \App\Enums\SourceControl::GITHUB, \App\Enums\SourceControl::BITBUCKET])] + #[BodyParam(name: 'name', description: 'The name of the storage provider.', required: true)] + #[BodyParam(name: 'token', description: 'The token if provider requires api token')] + #[BodyParam(name: 'url', description: 'The URL if the provider is Gitlab and it is self-hosted')] + #[BodyParam(name: 'username', description: 'The username if the provider is Bitbucket')] + #[BodyParam(name: 'password', description: 'The password if the provider is Bitbucket')] + #[ResponseFromApiResource(SourceControlResource::class, SourceControl::class)] + public function create(Request $request, Project $project): SourceControlResource + { + $this->authorize('create', SourceControl::class); + + $this->validate($request, ConnectSourceControl::rules($request->all())); + + $sourceControl = app(ConnectSourceControl::class)->connect(auth()->user(), $project, $request->all()); + + return new SourceControlResource($sourceControl); + } + + #[Get('{sourceControl}', name: 'api.projects.source-controls.show', middleware: 'ability:read')] + #[Endpoint(title: 'show')] + #[ResponseFromApiResource(SourceControlResource::class, SourceControl::class)] + public function show(Project $project, SourceControl $sourceControl) + { + $this->authorize('view', $sourceControl); + + $this->validateRoute($project, $sourceControl); + + return new SourceControlResource($sourceControl); + } + + #[Put('{sourceControl}', name: 'api.projects.source-controls.update', middleware: 'ability:write')] + #[Endpoint(title: 'update')] + #[BodyParam(name: 'name', description: 'The name of the storage provider.', required: true)] + #[BodyParam(name: 'token', description: 'The token if provider requires api token')] + #[BodyParam(name: 'url', description: 'The URL if the provider is Gitlab and it is self-hosted')] + #[BodyParam(name: 'username', description: 'The username if the provider is Bitbucket')] + #[BodyParam(name: 'password', description: 'The password if the provider is Bitbucket')] + #[BodyParam(name: 'global', description: 'Accessible in all projects', enum: [true, false])] + #[ResponseFromApiResource(SourceControlResource::class, SourceControl::class)] + public function update(Request $request, Project $project, SourceControl $sourceControl) + { + $this->authorize('update', $sourceControl); + + $this->validateRoute($project, $sourceControl); + + $this->validate($request, EditSourceControl::rules($sourceControl, $request->all())); + + $sourceControl = app(EditSourceControl::class)->edit($sourceControl, $project, $request->all()); + + return new SourceControlResource($sourceControl); + } + + #[Delete('{sourceControl}', name: 'api.projects.source-controls.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete')] + #[Response(status: 204)] + public function delete(Project $project, SourceControl $sourceControl) + { + $this->authorize('delete', $sourceControl); + + $this->validateRoute($project, $sourceControl); + + app(DeleteSourceControl::class)->delete($sourceControl); + + return response()->noContent(); + } + + private function validateRoute(Project $project, SourceControl $sourceControl): void + { + if (! $sourceControl->project_id) { + return; + } + + if ($project->id !== $sourceControl->project_id) { + abort(404, 'Source Control not found in project'); + } + } +} diff --git a/app/Http/Controllers/API/StorageProviderController.php b/app/Http/Controllers/API/StorageProviderController.php new file mode 100644 index 0000000..96ac92e --- /dev/null +++ b/app/Http/Controllers/API/StorageProviderController.php @@ -0,0 +1,116 @@ +authorize('viewAny', StorageProvider::class); + + $storageProviders = StorageProvider::getByProjectId($project->id)->simplePaginate(25); + + return StorageProviderResource::collection($storageProviders); + } + + #[Post('/', name: 'api.projects.storage-providers.create', middleware: 'ability:write')] + #[Endpoint(title: 'create')] + #[BodyParam(name: 'provider', description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)', required: true)] + #[BodyParam(name: 'name', description: 'The name of the storage provider.', required: true)] + #[BodyParam(name: 'token', description: 'The token if provider requires api token')] + #[BodyParam(name: 'key', description: 'The key if provider requires key')] + #[BodyParam(name: 'secret', description: 'The secret if provider requires key')] + #[ResponseFromApiResource(StorageProviderResource::class, StorageProvider::class)] + public function create(Request $request, Project $project): StorageProviderResource + { + $this->authorize('create', StorageProvider::class); + + $this->validate($request, CreateStorageProvider::rules($request->all())); + + $storageProvider = app(CreateStorageProvider::class)->create(auth()->user(), $project, $request->all()); + + return new StorageProviderResource($storageProvider); + } + + #[Get('{storageProvider}', name: 'api.projects.storage-providers.show', middleware: 'ability:read')] + #[Endpoint(title: 'show')] + #[ResponseFromApiResource(StorageProviderResource::class, StorageProvider::class)] + public function show(Project $project, StorageProvider $storageProvider) + { + $this->authorize('view', $storageProvider); + + $this->validateRoute($project, $storageProvider); + + return new StorageProviderResource($storageProvider); + } + + #[Put('{storageProvider}', name: 'api.projects.storage-providers.update', middleware: 'ability:write')] + #[Endpoint(title: 'update')] + #[BodyParam(name: 'name', description: 'The name of the storage provider.', required: true)] + #[BodyParam(name: 'global', description: 'Accessible in all projects', enum: [true, false])] + #[ResponseFromApiResource(StorageProviderResource::class, StorageProvider::class)] + public function update(Request $request, Project $project, StorageProvider $storageProvider) + { + $this->authorize('update', $storageProvider); + + $this->validateRoute($project, $storageProvider); + + $this->validate($request, EditStorageProvider::rules()); + + $storageProvider = app(EditStorageProvider::class)->edit($storageProvider, $project, $request->all()); + + return new StorageProviderResource($storageProvider); + } + + #[Delete('{storageProvider}', name: 'api.projects.storage-providers.delete', middleware: 'ability:write')] + #[Endpoint(title: 'delete')] + #[Response(status: 204)] + public function delete(Project $project, StorageProvider $storageProvider) + { + $this->authorize('delete', $storageProvider); + + $this->validateRoute($project, $storageProvider); + + app(DeleteStorageProvider::class)->delete($storageProvider); + + return response()->noContent(); + } + + private function validateRoute(Project $project, StorageProvider $storageProvider): void + { + if (! $storageProvider->project_id) { + return; + } + + if ($project->id !== $storageProvider->project_id) { + abort(404, 'Storage provider not found in project'); + } + } +} diff --git a/app/Http/Controllers/ConsoleController.php b/app/Http/Controllers/ConsoleController.php index 4812d8c..84102bf 100644 --- a/app/Http/Controllers/ConsoleController.php +++ b/app/Http/Controllers/ConsoleController.php @@ -5,9 +5,13 @@ use App\Models\Server; use Illuminate\Http\Request; use Illuminate\Validation\Rule; +use Spatie\RouteAttributes\Attributes\Middleware; +use Spatie\RouteAttributes\Attributes\Post; +#[Middleware('auth')] class ConsoleController extends Controller { + #[Post('/{server}/console', name: 'servers.console.run')] public function run(Server $server, Request $request) { $this->authorize('update', $server); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 9d5f474..4d3e196 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -62,5 +62,9 @@ class Kernel extends HttpKernel 'signed' => \App\Http\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class, + 'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class, + 'has-project' => \App\Http\Middleware\HasProjectMiddleware::class, + 'can-see-project' => \App\Http\Middleware\CanSeeProjectMiddleware::class, ]; } diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index d4ef644..aa87d36 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -12,6 +12,6 @@ class Authenticate extends Middleware */ protected function redirectTo(Request $request): ?string { - return $request->expectsJson() ? null : route('login'); + return $request->expectsJson() ? null : url('/'); } } diff --git a/app/Http/Middleware/CanSeeProjectMiddleware.php b/app/Http/Middleware/CanSeeProjectMiddleware.php new file mode 100644 index 0000000..b51cacb --- /dev/null +++ b/app/Http/Middleware/CanSeeProjectMiddleware.php @@ -0,0 +1,26 @@ +user(); + + /** @var Project $project */ + $project = $request->route('project'); + + if (! $user->can('view', $project)) { + abort(403, 'You do not have permission to view this project.'); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/HasProjectMiddleware.php b/app/Http/Middleware/HasProjectMiddleware.php new file mode 100644 index 0000000..af66c62 --- /dev/null +++ b/app/Http/Middleware/HasProjectMiddleware.php @@ -0,0 +1,32 @@ +user(); + if (! $user) { + return $next($request); + } + + if (! $user->currentProject) { + if ($user->allProjects()->count() > 0) { + $user->current_project_id = $user->projects->first()->id; + $user->save(); + + return $next($request); + } + + abort(403, 'You must have a project to access the panel.'); + } + + return $next($request); + } +} diff --git a/app/Http/Resources/CronJobResource.php b/app/Http/Resources/CronJobResource.php new file mode 100644 index 0000000..6a923f7 --- /dev/null +++ b/app/Http/Resources/CronJobResource.php @@ -0,0 +1,25 @@ + $this->id, + 'server_id' => $this->server_id, + 'command' => $this->command, + 'user' => $this->user, + 'frequency' => $this->frequency, + 'status' => $this->status, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/DatabaseResource.php b/app/Http/Resources/DatabaseResource.php new file mode 100644 index 0000000..489d125 --- /dev/null +++ b/app/Http/Resources/DatabaseResource.php @@ -0,0 +1,23 @@ + $this->id, + 'server_id' => $this->server_id, + 'name' => $this->name, + 'status' => $this->status, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/DatabaseUserResource.php b/app/Http/Resources/DatabaseUserResource.php new file mode 100644 index 0000000..050cc94 --- /dev/null +++ b/app/Http/Resources/DatabaseUserResource.php @@ -0,0 +1,25 @@ + $this->id, + 'server_id' => $this->server_id, + 'username' => $this->username, + 'databases' => $this->databases, + 'host' => $this->host, + 'status' => $this->status, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/FirewallRuleResource.php b/app/Http/Resources/FirewallRuleResource.php new file mode 100644 index 0000000..0e0db2e --- /dev/null +++ b/app/Http/Resources/FirewallRuleResource.php @@ -0,0 +1,28 @@ + $this->id, + 'server_id' => $this->server_id, + 'type' => $this->type, + 'protocol' => $this->protocol, + 'port' => $this->port, + 'source' => $this->source, + 'mask' => $this->mask, + 'note' => $this->note, + 'status' => $this->status, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/ProjectResource.php b/app/Http/Resources/ProjectResource.php new file mode 100644 index 0000000..e7e2e9e --- /dev/null +++ b/app/Http/Resources/ProjectResource.php @@ -0,0 +1,21 @@ + $this->id, + 'name' => $this->name, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/ServerProviderResource.php b/app/Http/Resources/ServerProviderResource.php new file mode 100644 index 0000000..f515ae9 --- /dev/null +++ b/app/Http/Resources/ServerProviderResource.php @@ -0,0 +1,24 @@ + $this->id, + 'project_id' => $this->project_id, + 'global' => is_null($this->project_id), + 'name' => $this->profile, + 'provider' => $this->provider, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/ServerResource.php b/app/Http/Resources/ServerResource.php new file mode 100644 index 0000000..b918788 --- /dev/null +++ b/app/Http/Resources/ServerResource.php @@ -0,0 +1,42 @@ + $this->id, + 'project_id' => $this->project_id, + 'user_id' => $this->user_id, + 'provider_id' => $this->provider_id, + 'name' => $this->name, + 'ssh_user' => $this->ssh_user, + 'ip' => $this->ip, + 'local_ip' => $this->local_ip, + 'port' => $this->port, + 'os' => $this->os, + 'type' => $this->type, + 'type_data' => $this->type_data, + 'provider' => $this->provider, + 'provider_data' => $this->provider_data, + 'public_key' => $this->public_key, + 'status' => $this->status, + 'auto_update' => $this->auto_update, + 'available_updates' => $this->available_updates, + 'security_updates' => $this->security_updates, + 'progress' => $this->progress, + 'progress_step' => $this->progress_step, + 'updates' => $this->updates, + 'last_update_check' => $this->last_update_check, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/ServiceResource.php b/app/Http/Resources/ServiceResource.php new file mode 100644 index 0000000..d7e7570 --- /dev/null +++ b/app/Http/Resources/ServiceResource.php @@ -0,0 +1,28 @@ + $this->id, + 'server_id' => $this->server_id, + 'type' => $this->type, + 'type_data' => $this->type_data, + 'name' => $this->name, + 'version' => $this->version, + 'unit' => $this->unit, + 'status' => $this->status, + 'is_default' => $this->is_default, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/SiteResource.php b/app/Http/Resources/SiteResource.php new file mode 100644 index 0000000..4d97591 --- /dev/null +++ b/app/Http/Resources/SiteResource.php @@ -0,0 +1,34 @@ + $this->id, + 'server_id' => $this->server_id, + 'source_control_id' => $this->source_control_id, + 'type' => $this->type, + 'type_data' => $this->type_data, + 'domain' => $this->domain, + 'aliases' => $this->aliases, + 'web_directory' => $this->web_directory, + 'path' => $this->path, + 'php_version' => $this->php_version, + 'repository' => $this->repository, + 'branch' => $this->branch, + 'status' => $this->status, + 'port' => $this->port, + 'progress' => $this->progress, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/SourceControlResource.php b/app/Http/Resources/SourceControlResource.php new file mode 100644 index 0000000..b3826a0 --- /dev/null +++ b/app/Http/Resources/SourceControlResource.php @@ -0,0 +1,24 @@ + $this->id, + 'project_id' => $this->project_id, + 'global' => is_null($this->project_id), + 'name' => $this->profile, + 'provider' => $this->provider, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/SshKeyResource.php b/app/Http/Resources/SshKeyResource.php new file mode 100644 index 0000000..1b2fbf9 --- /dev/null +++ b/app/Http/Resources/SshKeyResource.php @@ -0,0 +1,22 @@ + $this->id, + 'user' => $this->user_id ? new UserResource($this->user) : null, + 'name' => $this->name, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/StorageProviderResource.php b/app/Http/Resources/StorageProviderResource.php new file mode 100644 index 0000000..55973f5 --- /dev/null +++ b/app/Http/Resources/StorageProviderResource.php @@ -0,0 +1,24 @@ + $this->id, + 'project_id' => $this->project_id, + 'global' => is_null($this->project_id), + 'name' => $this->profile, + 'provider' => $this->provider, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php new file mode 100644 index 0000000..430c6ee --- /dev/null +++ b/app/Http/Resources/UserResource.php @@ -0,0 +1,22 @@ + $this->id, + 'name' => $this->name, + 'email' => $this->email, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Models/PersonalAccessToken.php b/app/Models/PersonalAccessToken.php new file mode 100644 index 0000000..b6981ad --- /dev/null +++ b/app/Models/PersonalAccessToken.php @@ -0,0 +1,23 @@ +projects()->count() === 0) { - $user->createDefaultProject(); - $user->refresh(); - } - if (! $user->currentProject) { - $user->current_project_id = $user->projects()->first()->id; - $user->save(); - } - }); - } - public function servers(): HasMany { return $this->hasMany(Server::class); @@ -118,9 +104,19 @@ public function storageProvider(string $provider): HasOne return $this->hasOne(StorageProvider::class)->where('provider', $provider); } + public function allProjects(): Builder|BelongsToMany + { + if ($this->isAdmin()) { + return Project::query(); + } + + return $this->projects(); + } + public function projects(): BelongsToMany { - return $this->belongsToMany(Project::class, 'user_project')->withTimestamps(); + return $this->belongsToMany(Project::class, 'user_project') + ->withTimestamps(); } public function currentProject(): HasOne diff --git a/app/Policies/PersonalAccessTokenPolicy.php b/app/Policies/PersonalAccessTokenPolicy.php new file mode 100644 index 0000000..d671ab1 --- /dev/null +++ b/app/Policies/PersonalAccessTokenPolicy.php @@ -0,0 +1,42 @@ +isAdmin(); + } + + public function view(User $user, PersonalAccessToken $personalAccessToken): bool + { + return $user->isAdmin(); + } + + public function create(User $user): bool + { + return $user->isAdmin(); + } + + public function update(User $user, PersonalAccessToken $personalAccessToken): bool + { + return $user->isAdmin(); + } + + public function delete(User $user, PersonalAccessToken $personalAccessToken): bool + { + return $user->isAdmin(); + } + + public function deleteMany(User $user): bool + { + return $user->isAdmin(); + } +} diff --git a/app/Policies/ServerPolicy.php b/app/Policies/ServerPolicy.php index 501cae7..0e767ab 100644 --- a/app/Policies/ServerPolicy.php +++ b/app/Policies/ServerPolicy.php @@ -2,14 +2,15 @@ namespace App\Policies; +use App\Models\Project; use App\Models\Server; use App\Models\User; class ServerPolicy { - public function viewAny(User $user): bool + public function viewAny(User $user, Project $project): bool { - return $user->isAdmin() || $user->currentProject?->users->contains($user); + return $user->isAdmin() || $project->users->contains($user); } public function view(User $user, Server $server): bool @@ -17,9 +18,9 @@ public function view(User $user, Server $server): bool return $user->isAdmin() || $server->project->users->contains($user); } - public function create(User $user): bool + public function create(User $user, Project $project): bool { - return $user->isAdmin() || $user->currentProject?->users->contains($user); + return $user->isAdmin() || $project->users->contains($user); } public function update(User $user, Server $server): bool diff --git a/app/Policies/ServerProviderPolicy.php b/app/Policies/ServerProviderPolicy.php index ef91bd8..0a82d18 100644 --- a/app/Policies/ServerProviderPolicy.php +++ b/app/Policies/ServerProviderPolicy.php @@ -12,26 +12,29 @@ class ServerProviderPolicy public function viewAny(User $user): bool { - return $user->isAdmin(); + return true; } public function view(User $user, ServerProvider $serverProvider): bool { - return $user->isAdmin(); + return $user->isAdmin() || + $user->id === $serverProvider->user_id || + $serverProvider->project_id === null || + $serverProvider->project?->users()->where('user_id', $user->id)->exists(); } public function create(User $user): bool { - return $user->isAdmin(); + return true; } public function update(User $user, ServerProvider $serverProvider): bool { - return $user->isAdmin(); + return $user->isAdmin() || $user->id === $serverProvider->user_id; } public function delete(User $user, ServerProvider $serverProvider): bool { - return $user->isAdmin(); + return $user->isAdmin() || $user->id === $serverProvider->user_id; } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ed71e71..6babec7 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -5,9 +5,11 @@ use App\Helpers\FTP; use App\Helpers\Notifier; use App\Helpers\SSH; +use App\Models\PersonalAccessToken; use Illuminate\Http\Resources\Json\ResourceCollection; use Illuminate\Support\ServiceProvider; use Laravel\Fortify\Fortify; +use Laravel\Sanctum\Sanctum; class AppServiceProvider extends ServiceProvider { @@ -33,5 +35,7 @@ public function boot(): void $this->app->bind('ftp', function () { return new FTP; }); + + Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class); } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 4c26a19..fc2d894 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -6,7 +6,6 @@ use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; use Illuminate\Http\Request; use Illuminate\Support\Facades\RateLimiter; -use Illuminate\Support\Facades\Route; class RouteServiceProvider extends ServiceProvider { @@ -25,15 +24,6 @@ class RouteServiceProvider extends ServiceProvider public function boot(): void { $this->configureRateLimiting(); - - $this->routes(function () { - Route::middleware('api') - ->prefix('api') - ->group(base_path('routes/api.php')); - - Route::middleware('web') - ->group(base_path('routes/web.php')); - }); } /** diff --git a/app/Providers/WebServiceProvider.php b/app/Providers/WebServiceProvider.php index 67a8f9a..2166b08 100644 --- a/app/Providers/WebServiceProvider.php +++ b/app/Providers/WebServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Http\Middleware\HasProjectMiddleware; use App\Web\Pages\Settings\Projects\Widgets\SelectProject; use Exception; use Filament\Facades\Filament; @@ -102,6 +103,7 @@ public function panel(Panel $panel): Panel ]) ->authMiddleware([ Authenticate::class, + HasProjectMiddleware::class, ]) ->login() ->spa() diff --git a/app/SSH/Services/ProcessManager/Supervisor.php b/app/SSH/Services/ProcessManager/Supervisor.php index abc5074..cca0ee5 100644 --- a/app/SSH/Services/ProcessManager/Supervisor.php +++ b/app/SSH/Services/ProcessManager/Supervisor.php @@ -24,8 +24,6 @@ public function uninstall(): void $this->getScript('supervisor/uninstall-supervisor.sh'), 'uninstall-supervisor' ); - $status = $this->service->server->systemd()->status($this->service->unit); - $this->service->validateInstall($status); $this->service->server->os()->cleanup(); } diff --git a/app/SourceControlProviders/AbstractSourceControlProvider.php b/app/SourceControlProviders/AbstractSourceControlProvider.php index 9dcbea1..b9492e5 100755 --- a/app/SourceControlProviders/AbstractSourceControlProvider.php +++ b/app/SourceControlProviders/AbstractSourceControlProvider.php @@ -21,11 +21,6 @@ public function createRules(array $input): array { return [ 'token' => 'required', - 'url' => [ - 'nullable', - 'url:http,https', - 'ends_with:/', - ], ]; } @@ -36,6 +31,16 @@ public function createData(array $input): array ]; } + public function editRules(array $input): array + { + return $this->createRules($input); + } + + public function editData(array $input): array + { + return $this->createData($input); + } + public function data(): array { // support for older data diff --git a/app/SourceControlProviders/Gitlab.php b/app/SourceControlProviders/Gitlab.php index 4000a25..b7fe0b9 100755 --- a/app/SourceControlProviders/Gitlab.php +++ b/app/SourceControlProviders/Gitlab.php @@ -14,6 +14,18 @@ class Gitlab extends AbstractSourceControlProvider protected string $apiVersion = 'api/v4'; + public function createRules(array $input): array + { + return [ + 'token' => 'required', + 'url' => [ + 'nullable', + 'url:http,https', + 'ends_with:/', + ], + ]; + } + public function connect(): bool { $res = Http::withToken($this->data()['token']) diff --git a/app/SourceControlProviders/SourceControlProvider.php b/app/SourceControlProviders/SourceControlProvider.php index a695b75..d71731e 100755 --- a/app/SourceControlProviders/SourceControlProvider.php +++ b/app/SourceControlProviders/SourceControlProvider.php @@ -8,6 +8,10 @@ public function createRules(array $input): array; public function createData(array $input): array; + public function editRules(array $input): array; + + public function editData(array $input): array; + public function data(): array; public function connect(): bool; diff --git a/app/Support/helpers.php b/app/Support/helpers.php index ab5a41b..b8f2e47 100755 --- a/app/Support/helpers.php +++ b/app/Support/helpers.php @@ -38,12 +38,7 @@ function htmx(): HtmxResponse function vito_version(): string { - $version = exec('git describe --tags'); - if (str($version)->contains('-')) { - return str($version)->before('-').' (dev)'; - } - - return $version; + return config('app.version'); } function convert_time_format($string): string diff --git a/app/Traits/Enum.php b/app/Traits/Enum.php new file mode 100644 index 0000000..8085270 --- /dev/null +++ b/app/Traits/Enum.php @@ -0,0 +1,13 @@ +getConstants(); + } +} diff --git a/app/Web/Pages/Servers/Index.php b/app/Web/Pages/Servers/Index.php index 7ca0318..ed9b33a 100644 --- a/app/Web/Pages/Servers/Index.php +++ b/app/Web/Pages/Servers/Index.php @@ -34,7 +34,7 @@ public static function getNavigationItemActiveRoutePattern(): string public function mount(): void { - $this->authorize('viewAny', Server::class); + $this->authorize('viewAny', [Server::class, auth()->user()->currentProject]); } public function getWidgets(): array @@ -50,6 +50,8 @@ protected function getHeaderActions(): array 'public_key' => get_public_key_content(), ]); + $project = auth()->user()->currentProject; + return [ \Filament\Actions\Action::make('read-the-docs') ->label('Read the Docs') @@ -60,7 +62,7 @@ protected function getHeaderActions(): array \Filament\Actions\Action::make('create') ->label('Create a Server') ->icon('heroicon-o-plus') - ->authorize('create', Server::class) + ->authorize('create', [Server::class, auth()->user()->currentProject]) ->modalWidth(MaxWidth::FiveExtraLarge) ->slideOver() ->form([ @@ -74,7 +76,7 @@ protected function getHeaderActions(): array $set('region', null); $set('plan', null); }) - ->rules(fn ($get) => CreateServerAction::rules($get())['provider']), + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['provider']), AlertField::make('alert') ->warning() ->message(__('servers.create.public_key_warning')) @@ -82,7 +84,7 @@ protected function getHeaderActions(): array Select::make('server_provider') ->visible(fn ($get) => $get('provider') !== ServerProvider::CUSTOM) ->label('Server provider connection') - ->rules(fn ($get) => CreateServerAction::rules($get())['server_provider']) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['server_provider']) ->options(function ($get) { return \App\Models\ServerProvider::getByProjectId(auth()->user()->current_project_id) ->where('provider', $get('provider')) @@ -109,7 +111,7 @@ protected function getHeaderActions(): array ->schema([ Select::make('region') ->label('Region') - ->rules(fn ($get) => CreateServerAction::rules($get())['region']) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['region']) ->live() ->reactive() ->options(function ($get) { @@ -125,7 +127,7 @@ protected function getHeaderActions(): array ->searchable(), Select::make('plan') ->label('Plan') - ->rules(fn ($get) => CreateServerAction::rules($get())['plan']) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['plan']) ->reactive() ->options(function ($get) { if (! $get('server_provider') || ! $get('region')) { @@ -162,15 +164,15 @@ protected function getHeaderActions(): array ->visible(fn ($get) => $get('provider') === ServerProvider::CUSTOM), TextInput::make('name') ->label('Name') - ->rules(fn ($get) => CreateServerAction::rules($get())['name']), + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['name']), Grid::make() ->schema([ TextInput::make('ip') ->label('SSH IP Address') - ->rules(fn ($get) => CreateServerAction::rules($get())['ip']), + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['ip']), TextInput::make('port') ->label('SSH Port') - ->rules(fn ($get) => CreateServerAction::rules($get())['port']), + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['port']), ]) ->visible(fn ($get) => $get('provider') === ServerProvider::CUSTOM), Grid::make() @@ -178,7 +180,7 @@ protected function getHeaderActions(): array Select::make('os') ->label('OS') ->native(false) - ->rules(fn ($get) => CreateServerAction::rules($get())['os']) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['os']) ->options( collect(config('core.operating_systems')) ->mapWithKeys(fn ($value) => [$value => $value]) @@ -187,7 +189,7 @@ protected function getHeaderActions(): array ->label('Server Type') ->native(false) ->selectablePlaceholder(false) - ->rules(fn ($get) => CreateServerAction::rules($get())['type']) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['type']) ->options( collect(config('core.server_types')) ->mapWithKeys(fn ($value) => [$value => $value]) @@ -200,7 +202,7 @@ protected function getHeaderActions(): array ->label('Webserver') ->native(false) ->selectablePlaceholder(false) - ->rules(fn ($get) => CreateServerAction::rules($get())['webserver'] ?? []) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['webserver'] ?? []) ->options( collect(config('core.webservers'))->mapWithKeys(fn ($value) => [$value => $value]) ), @@ -208,7 +210,7 @@ protected function getHeaderActions(): array ->label('Database') ->native(false) ->selectablePlaceholder(false) - ->rules(fn ($get) => CreateServerAction::rules($get())['database'] ?? []) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['database'] ?? []) ->options( collect(config('core.databases_name')) ->mapWithKeys(fn ($value, $key) => [ @@ -219,7 +221,7 @@ protected function getHeaderActions(): array ->label('PHP') ->native(false) ->selectablePlaceholder(false) - ->rules(fn ($get) => CreateServerAction::rules($get())['php'] ?? []) + ->rules(fn ($get) => CreateServerAction::rules($project, $get())['php'] ?? []) ->options( collect(config('core.php_versions')) ->mapWithKeys(fn ($value) => [$value => $value]) @@ -229,7 +231,7 @@ protected function getHeaderActions(): array ->modalSubmitActionLabel('Create') ->action(function (array $data) { run_action($this, function () use ($data) { - $server = app(CreateServerAction::class)->create(auth()->user(), $data); + $server = app(CreateServerAction::class)->create(auth()->user(), auth()->user()->currentProject, $data); $this->redirect(View::getUrl(['server' => $server])); }); diff --git a/app/Web/Pages/Servers/Logs/Widgets/LogsList.php b/app/Web/Pages/Servers/Logs/Widgets/LogsList.php index 7649173..4cf7a8d 100644 --- a/app/Web/Pages/Servers/Logs/Widgets/LogsList.php +++ b/app/Web/Pages/Servers/Logs/Widgets/LogsList.php @@ -8,7 +8,6 @@ use Exception; use Filament\Forms\Components\DatePicker; use Filament\Tables\Actions\Action; -use Filament\Tables\Actions\BulkActionGroup; use Filament\Tables\Actions\DeleteAction; use Filament\Tables\Actions\DeleteBulkAction; use Filament\Tables\Columns\TextColumn; @@ -115,12 +114,10 @@ public function getTable(): Table ->color('danger') ->authorize(fn ($record) => auth()->user()->can('delete', $record)), ]) - ->bulkActions( - BulkActionGroup::make([ - DeleteBulkAction::make() - ->requiresConfirmation() - ->authorize(auth()->user()->can('deleteMany', [ServerLog::class, $this->server])), - ]) - ); + ->bulkActions([ + DeleteBulkAction::make() + ->requiresConfirmation() + ->authorize(auth()->user()->can('deleteMany', [ServerLog::class, $this->server])), + ]); } } diff --git a/app/Web/Pages/Servers/Settings.php b/app/Web/Pages/Servers/Settings.php index d148dfe..e90d654 100644 --- a/app/Web/Pages/Servers/Settings.php +++ b/app/Web/Pages/Servers/Settings.php @@ -21,7 +21,7 @@ class Settings extends Page public function mount(): void { - $this->authorize('update', $this->server); + $this->authorize('update', [$this->server, auth()->user()->currentProject]); } public function getWidgets(): array @@ -45,6 +45,7 @@ protected function getHeaderActions(): array ->requiresConfirmation() ->modalHeading('Delete Server') ->modalDescription('Once your server is deleted, all of its resources and data will be permanently deleted and can\'t be restored') + ->authorize('delete', $this->server) ->action(function () { try { $this->server->delete(); diff --git a/app/Web/Pages/Servers/View.php b/app/Web/Pages/Servers/View.php index dbc5e81..5c18d1f 100644 --- a/app/Web/Pages/Servers/View.php +++ b/app/Web/Pages/Servers/View.php @@ -18,7 +18,7 @@ class View extends Page public function mount(): void { - $this->authorize('view', $this->server); + $this->authorize('view', [$this->server, auth()->user()->currentProject]); $this->previousStatus = $this->server->status; } diff --git a/app/Web/Pages/Settings/APIKeys/Index.php b/app/Web/Pages/Settings/APIKeys/Index.php new file mode 100644 index 0000000..07d3d66 --- /dev/null +++ b/app/Web/Pages/Settings/APIKeys/Index.php @@ -0,0 +1,115 @@ +user()?->can('viewAny', PersonalAccessToken::class) ?? false; + } + + public function getWidgets(): array + { + return [ + [Widgets\ApiKeysList::class], + ]; + } + + public function unmountAction(bool $shouldCancelParentActions = true, bool $shouldCloseModal = true): void + { + parent::unmountAction($shouldCancelParentActions, $shouldCloseModal); + + $this->token = ''; + } + + protected function getHeaderActions(): array + { + return [ + Action::make('read-the-docs') + ->label('Read the Docs') + ->icon('heroicon-o-document-text') + ->color('gray') + ->url(config('scribe.static.url')) + ->openUrlInNewTab(), + Action::make('create') + ->label('Create new Key') + ->icon('heroicon-o-plus') + ->modalHeading('Create a new Key') + ->modalSubmitActionLabel('Create') + ->form(function () { + if ($this->token) { + return []; + } + + return [ + TextInput::make('name') + ->label('Token Name') + ->required(), + Radio::make('permission') + ->options([ + 'read' => 'Read', + 'write' => 'Read & Write', + ]) + ->required(), + ]; + }) + ->infolist(function () { + if ($this->token) { + return [ + TextEntry::make('token') + ->state($this->token) + ->tooltip('Copy') + ->copyable() + ->helperText('You can see the token only one!'), + ]; + } + + return []; + }) + ->authorize('create', PersonalAccessToken::class) + ->modalWidth(MaxWidth::Large) + ->action(function (array $data) { + $permissions = ['read']; + if ($data['permission'] === 'write') { + $permissions[] = 'write'; + } + $token = auth()->user()->createToken($data['name'], $permissions); + + $this->dispatch('$refresh'); + + $this->token = $token->plainTextToken; + + $this->halt(); + }) + ->modalSubmitAction(function () { + if ($this->token) { + return false; + } + }) + ->closeModalByClickingAway(fn () => ! $this->token), + ]; + } +} diff --git a/app/Web/Pages/Settings/APIKeys/Widgets/ApiKeysList.php b/app/Web/Pages/Settings/APIKeys/Widgets/ApiKeysList.php new file mode 100644 index 0000000..cfc56ee --- /dev/null +++ b/app/Web/Pages/Settings/APIKeys/Widgets/ApiKeysList.php @@ -0,0 +1,62 @@ +user()->tokens()->getQuery(); + } + + protected function getTableColumns(): array + { + return [ + TextColumn::make('name') + ->searchable() + ->sortable(), + TextColumn::make('abilities') + ->searchable() + ->sortable(), + TextColumn::make('created_at') + ->label('Created At') + ->formatStateUsing(fn (PersonalAccessToken $record) => $record->created_at_by_timezone) + ->searchable() + ->sortable(), + TextColumn::make('last_used_at') + ->label('Last Used At') + ->formatStateUsing(fn (PersonalAccessToken $record) => $record->getDateTimeByTimezone($record->last_used_at)) + ->searchable() + ->sortable(), + ]; + } + + public function getTable(): Table + { + return $this->table + ->heading('') + ->actions([ + DeleteAction::make('delete') + ->modalHeading('Delete Token') + ->authorize(fn (PersonalAccessToken $record) => auth()->user()->can('delete', $record)) + ->using(function (array $data, PersonalAccessToken $record) { + $record->delete(); + }), + ]) + ->bulkActions([ + DeleteBulkAction::make() + ->requiresConfirmation() + ->authorize(auth()->user()->can('deleteMany', PersonalAccessToken::class)), + ]); + } +} diff --git a/app/Web/Pages/Settings/NotificationChannels/Widgets/NotificationChannelsList.php b/app/Web/Pages/Settings/NotificationChannels/Widgets/NotificationChannelsList.php index 5bfbabd..57cf388 100644 --- a/app/Web/Pages/Settings/NotificationChannels/Widgets/NotificationChannelsList.php +++ b/app/Web/Pages/Settings/NotificationChannels/Widgets/NotificationChannelsList.php @@ -15,9 +15,7 @@ class NotificationChannelsList extends Widget { - protected $listeners = [ - '$refresh' => 'refreshTable', - ]; + protected $listeners = ['$refresh']; protected function getTableQuery(): Builder { diff --git a/app/Web/Pages/Settings/Projects/Widgets/SelectProject.php b/app/Web/Pages/Settings/Projects/Widgets/SelectProject.php index 6148fab..55e7976 100644 --- a/app/Web/Pages/Settings/Projects/Widgets/SelectProject.php +++ b/app/Web/Pages/Settings/Projects/Widgets/SelectProject.php @@ -4,7 +4,6 @@ use App\Models\Project; use Filament\Widgets\Widget; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; class SelectProject extends Widget @@ -20,15 +19,7 @@ class SelectProject extends Widget public function mount(): void { $this->currentProject = auth()->user()->currentProject; - $this->projects = Project::query() - ->where(function (Builder $query) { - if (auth()->user()->isAdmin()) { - return; - } - $query->where('user_id', auth()->id()) - ->orWhereHas('users', fn ($query) => $query->where('user_id', auth()->id())); - }) - ->get(); + $this->projects = auth()->user()->allProjects()->get(); } public function updateProject(Project $project): void diff --git a/app/Web/Pages/Settings/ServerProviders/Actions/Create.php b/app/Web/Pages/Settings/ServerProviders/Actions/Create.php index 8504885..dd634b7 100644 --- a/app/Web/Pages/Settings/ServerProviders/Actions/Create.php +++ b/app/Web/Pages/Settings/ServerProviders/Actions/Create.php @@ -8,6 +8,7 @@ use Filament\Forms\Components\Checkbox; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; +use Filament\Forms\Get; use Filament\Notifications\Notification; class Create @@ -23,29 +24,22 @@ public static function form(): array ) ->live() ->reactive() - ->rules(CreateServerProvider::rules()['provider']), + ->rules(fn (Get $get) => CreateServerProvider::rules($get())['provider']), TextInput::make('name') - ->rules(CreateServerProvider::rules()['name']), + ->rules(fn (Get $get) => CreateServerProvider::rules($get())['name']), TextInput::make('token') ->label('API Key') ->validationAttribute('API Key') - ->visible(fn ($get) => in_array($get('provider'), [ - ServerProvider::DIGITALOCEAN, - ServerProvider::LINODE, - ServerProvider::VULTR, - ServerProvider::HETZNER, - ])) - ->rules(fn ($get) => CreateServerProvider::providerRules($get())['token']), + ->visible(fn ($get) => isset(CreateServerProvider::rules($get())['token'])) + ->rules(fn (Get $get) => CreateServerProvider::rules($get())['token']), TextInput::make('key') ->label('Access Key') - ->visible(function ($get) { - return $get('provider') == ServerProvider::AWS; - }) - ->rules(fn ($get) => CreateServerProvider::providerRules($get())['key']), + ->visible(fn ($get) => isset(CreateServerProvider::rules($get())['key'])) + ->rules(fn (Get $get) => CreateServerProvider::rules($get())['key']), TextInput::make('secret') ->label('Secret') - ->visible(fn ($get) => $get('provider') == ServerProvider::AWS) - ->rules(fn ($get) => CreateServerProvider::providerRules($get())['secret']), + ->visible(fn ($get) => isset(CreateServerProvider::rules($get())['secret'])) + ->rules(fn (Get $get) => CreateServerProvider::rules($get())['secret']), Checkbox::make('global') ->label('Is Global (Accessible in all projects)'), ]; @@ -57,7 +51,7 @@ public static function form(): array public static function action(array $data): void { try { - app(CreateServerProvider::class)->create(auth()->user(), $data); + app(CreateServerProvider::class)->create(auth()->user(), auth()->user()->currentProject, $data); } catch (Exception $e) { Notification::make() ->title($e->getMessage()) diff --git a/app/Web/Pages/Settings/ServerProviders/Actions/Edit.php b/app/Web/Pages/Settings/ServerProviders/Actions/Edit.php index 69cff78..32e221c 100644 --- a/app/Web/Pages/Settings/ServerProviders/Actions/Edit.php +++ b/app/Web/Pages/Settings/ServerProviders/Actions/Edit.php @@ -22,6 +22,6 @@ public static function form(): array public static function action(ServerProvider $provider, array $data): void { - app(EditServerProvider::class)->edit($provider, auth()->user(), $data); + app(EditServerProvider::class)->edit($provider, auth()->user()->currentProject, $data); } } diff --git a/app/Web/Pages/Settings/SourceControls/Actions/Create.php b/app/Web/Pages/Settings/SourceControls/Actions/Create.php index c33c5a9..d4df868 100644 --- a/app/Web/Pages/Settings/SourceControls/Actions/Create.php +++ b/app/Web/Pages/Settings/SourceControls/Actions/Create.php @@ -56,7 +56,7 @@ public static function form(): array public static function action(array $data): void { try { - app(ConnectSourceControl::class)->connect(auth()->user(), $data); + app(ConnectSourceControl::class)->connect(auth()->user(), auth()->user()->currentProject, $data); } catch (Exception $e) { Notification::make() ->title($e->getMessage()) diff --git a/app/Web/Pages/Settings/SourceControls/Actions/Edit.php b/app/Web/Pages/Settings/SourceControls/Actions/Edit.php index 5d9b06e..1861b67 100644 --- a/app/Web/Pages/Settings/SourceControls/Actions/Edit.php +++ b/app/Web/Pages/Settings/SourceControls/Actions/Edit.php @@ -2,9 +2,8 @@ namespace App\Web\Pages\Settings\SourceControls\Actions; -use App\Actions\SourceControl\ConnectSourceControl; use App\Actions\SourceControl\EditSourceControl; -use App\Enums\SourceControl; +use App\Models\SourceControl; use Exception; use Filament\Forms\Components\Checkbox; use Filament\Forms\Components\TextInput; @@ -13,30 +12,27 @@ class Edit { - public static function form(): array + public static function form(SourceControl $sourceControl): array { return [ TextInput::make('name') - ->rules(fn (Get $get) => ConnectSourceControl::rules($get())['name']), + ->rules(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['name']), TextInput::make('token') ->label('API Key') ->validationAttribute('API Key') - ->visible(fn ($get) => in_array($get('provider'), [ - SourceControl::GITHUB, - SourceControl::GITLAB, - ])) - ->rules(fn (Get $get) => ConnectSourceControl::rules($get())['token']), + ->visible(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['token'] ?? false) + ->rules(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['token']), TextInput::make('url') ->label('URL (optional)') - ->visible(fn ($get) => $get('provider') == SourceControl::GITLAB) - ->rules(fn (Get $get) => ConnectSourceControl::rules($get())['url']) + ->visible(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['url'] ?? false) + ->rules(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['url']) ->helperText('If you run a self-managed gitlab enter the url here, leave empty to use gitlab.com'), TextInput::make('username') - ->visible(fn ($get) => $get('provider') == SourceControl::BITBUCKET) - ->rules(fn (Get $get) => ConnectSourceControl::rules($get())['username']), + ->visible(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['username'] ?? false) + ->rules(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['username']), TextInput::make('password') - ->visible(fn ($get) => $get('provider') == SourceControl::BITBUCKET) - ->rules(fn (Get $get) => ConnectSourceControl::rules($get())['password']), + ->visible(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['password'] ?? false) + ->rules(fn (Get $get) => EditSourceControl::rules($sourceControl, $get())['password']), Checkbox::make('global') ->label('Is Global (Accessible in all projects)'), ]; @@ -45,10 +41,10 @@ public static function form(): array /** * @throws Exception */ - public static function action(\App\Models\SourceControl $sourceControl, array $data): void + public static function action(SourceControl $sourceControl, array $data): void { try { - app(EditSourceControl::class)->edit($sourceControl, auth()->user(), $data); + app(EditSourceControl::class)->edit($sourceControl, auth()->user()->currentProject, $data); } catch (Exception $e) { Notification::make() ->title($e->getMessage()) diff --git a/app/Web/Pages/Settings/SourceControls/Widgets/SourceControlsList.php b/app/Web/Pages/Settings/SourceControls/Widgets/SourceControlsList.php index bfc0353..46c9bff 100644 --- a/app/Web/Pages/Settings/SourceControls/Widgets/SourceControlsList.php +++ b/app/Web/Pages/Settings/SourceControls/Widgets/SourceControlsList.php @@ -69,7 +69,7 @@ public function getTable(): Table 'global' => $record->project_id === null, ]; }) - ->form(Edit::form()) + ->form(fn (SourceControl $record) => Edit::form($record)) ->authorize(fn (SourceControl $record) => auth()->user()->can('update', $record)) ->using(fn (array $data, SourceControl $record) => Edit::action($record, $data)) ->modalWidth(MaxWidth::Medium), diff --git a/app/Web/Pages/Settings/StorageProviders/Actions/Create.php b/app/Web/Pages/Settings/StorageProviders/Actions/Create.php index 60e348f..298a6e7 100644 --- a/app/Web/Pages/Settings/StorageProviders/Actions/Create.php +++ b/app/Web/Pages/Settings/StorageProviders/Actions/Create.php @@ -126,7 +126,7 @@ public static function form(): array public static function action(array $data): void { try { - app(CreateStorageProvider::class)->create(auth()->user(), $data); + app(CreateStorageProvider::class)->create(auth()->user(), auth()->user()->currentProject, $data); } catch (Exception $e) { Notification::make() ->title($e->getMessage()) diff --git a/app/Web/Pages/Settings/StorageProviders/Actions/Edit.php b/app/Web/Pages/Settings/StorageProviders/Actions/Edit.php index 60047e6..c0f7be0 100644 --- a/app/Web/Pages/Settings/StorageProviders/Actions/Edit.php +++ b/app/Web/Pages/Settings/StorageProviders/Actions/Edit.php @@ -22,6 +22,6 @@ public static function form(): array public static function action(StorageProvider $provider, array $data): void { - app(EditStorageProvider::class)->edit($provider, auth()->user(), $data); + app(EditStorageProvider::class)->edit($provider, auth()->user()->currentProject, $data); } } diff --git a/composer.json b/composer.json index 5a51a75..c33f917 100644 --- a/composer.json +++ b/composer.json @@ -15,11 +15,14 @@ "filament/filament": "^3.2", "laravel/fortify": "^1.17", "laravel/framework": "^11.0", + "laravel/sanctum": "^4.0", "laravel/tinker": "^2.8", - "phpseclib/phpseclib": "~3.0" + "phpseclib/phpseclib": "~3.0", + "spatie/laravel-route-attributes": "^1.24" }, "require-dev": { "fakerphp/faker": "^1.9.1", + "knuckleswtf/scribe": "^4.37", "laradumps/laradumps": "^3.0", "laravel/pint": "^1.10", "laravel/sail": "^1.18", diff --git a/composer.lock b/composer.lock index 9cc52df..f394b67 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cd410bf2bc1c93170c1426bcdf231181", + "content-hash": "414770551e501c730f96ce36cc531c1a", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -74,16 +74,16 @@ }, { "name": "aws/aws-crt-php", - "version": "v1.2.6", + "version": "v1.2.7", "source": { "type": "git", "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "a63485b65b6b3367039306496d49737cf1995408" + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/a63485b65b6b3367039306496d49737cf1995408", - "reference": "a63485b65b6b3367039306496d49737cf1995408", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e", "shasum": "" }, "require": { @@ -122,22 +122,22 @@ ], "support": { "issues": "https://github.com/awslabs/aws-crt-php/issues", - "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.6" + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7" }, - "time": "2024-06-13T17:21:28+00:00" + "time": "2024-10-18T22:15:13+00:00" }, { "name": "aws/aws-sdk-php", - "version": "3.324.1", + "version": "3.325.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "5b824a9b8015a38f18c53b023975c0f63c7bd3dc" + "reference": "5ac57c98062f1c45d094c2baa94a7e557989465f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5b824a9b8015a38f18c53b023975c0f63c7bd3dc", - "reference": "5b824a9b8015a38f18c53b023975c0f63c7bd3dc", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5ac57c98062f1c45d094c2baa94a7e557989465f", + "reference": "5ac57c98062f1c45d094c2baa94a7e557989465f", "shasum": "" }, "require": { @@ -220,9 +220,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.324.1" + "source": "https://github.com/aws/aws-sdk-php/tree/3.325.1" }, - "time": "2024-10-11T18:22:01+00:00" + "time": "2024-10-31T18:15:14+00:00" }, { "name": "bacon/bacon-qr-code", @@ -349,16 +349,16 @@ }, { "name": "blade-ui-kit/blade-icons", - "version": "1.7.1", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/blade-ui-kit/blade-icons.git", - "reference": "8f787baf09d88cdfd6ec4dbaba11ebfa885f0595" + "reference": "75a54a3f5a2810fcf6574ab23e91b6cc229a1b53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/8f787baf09d88cdfd6ec4dbaba11ebfa885f0595", - "reference": "8f787baf09d88cdfd6ec4dbaba11ebfa885f0595", + "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/75a54a3f5a2810fcf6574ab23e91b6cc229a1b53", + "reference": "75a54a3f5a2810fcf6574ab23e91b6cc229a1b53", "shasum": "" }, "require": { @@ -426,7 +426,7 @@ "type": "paypal" } ], - "time": "2024-08-14T14:25:11+00:00" + "time": "2024-10-17T17:38:00+00:00" }, { "name": "brick/math", @@ -1244,16 +1244,16 @@ }, { "name": "filament/actions", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", - "reference": "886108b59ce99edc26f5bc1231134a95ec58718a" + "reference": "3badf1a1589bf70fdc625130f6dfc1ca2146a32f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/actions/zipball/886108b59ce99edc26f5bc1231134a95ec58718a", - "reference": "886108b59ce99edc26f5bc1231134a95ec58718a", + "url": "https://api.github.com/repos/filamentphp/actions/zipball/3badf1a1589bf70fdc625130f6dfc1ca2146a32f", + "reference": "3badf1a1589bf70fdc625130f6dfc1ca2146a32f", "shasum": "" }, "require": { @@ -1293,20 +1293,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-09T11:19:22+00:00" + "time": "2024-10-31T13:38:12+00:00" }, { "name": "filament/filament", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "84f839b4b42549c0d4bd231648da17561ada70c2" + "reference": "076f5367a3dfe5f6864d117f6826ca7821586931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/84f839b4b42549c0d4bd231648da17561ada70c2", - "reference": "84f839b4b42549c0d4bd231648da17561ada70c2", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/076f5367a3dfe5f6864d117f6826ca7821586931", + "reference": "076f5367a3dfe5f6864d117f6826ca7821586931", "shasum": "" }, "require": { @@ -1358,20 +1358,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:12+00:00" + "time": "2024-10-31T13:38:14+00:00" }, { "name": "filament/forms", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "896c868cca474b2e925a3e6162b7c76d8ff3e5fc" + "reference": "c863b5765b871485a2c624c43a0eb6e957a04b54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/896c868cca474b2e925a3e6162b7c76d8ff3e5fc", - "reference": "896c868cca474b2e925a3e6162b7c76d8ff3e5fc", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/c863b5765b871485a2c624c43a0eb6e957a04b54", + "reference": "c863b5765b871485a2c624c43a0eb6e957a04b54", "shasum": "" }, "require": { @@ -1414,20 +1414,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-09T11:19:26+00:00" + "time": "2024-10-31T13:38:16+00:00" }, { "name": "filament/infolists", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", - "reference": "fc5f01c094fe25ef906f3e1b88d3d8883a73d6be" + "reference": "2d934d4d7f420fc1165ced33df0959a656163a0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/infolists/zipball/fc5f01c094fe25ef906f3e1b88d3d8883a73d6be", - "reference": "fc5f01c094fe25ef906f3e1b88d3d8883a73d6be", + "url": "https://api.github.com/repos/filamentphp/infolists/zipball/2d934d4d7f420fc1165ced33df0959a656163a0c", + "reference": "2d934d4d7f420fc1165ced33df0959a656163a0c", "shasum": "" }, "require": { @@ -1465,20 +1465,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:09+00:00" + "time": "2024-10-24T13:47:00+00:00" }, { "name": "filament/notifications", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", - "reference": "a5f684b690354630210fc9a90bd06da9b1f6ae82" + "reference": "c19df07c801c5550de0d30957c5a316f53019533" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/notifications/zipball/a5f684b690354630210fc9a90bd06da9b1f6ae82", - "reference": "a5f684b690354630210fc9a90bd06da9b1f6ae82", + "url": "https://api.github.com/repos/filamentphp/notifications/zipball/c19df07c801c5550de0d30957c5a316f53019533", + "reference": "c19df07c801c5550de0d30957c5a316f53019533", "shasum": "" }, "require": { @@ -1517,20 +1517,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:11+00:00" + "time": "2024-10-23T07:36:14+00:00" }, { "name": "filament/support", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "31fcff80b873b4decdba10d5f7010310e12c8e94" + "reference": "e7174cee7e1d08205f7120d0dcc0d00d9bdd4d32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/31fcff80b873b4decdba10d5f7010310e12c8e94", - "reference": "31fcff80b873b4decdba10d5f7010310e12c8e94", + "url": "https://api.github.com/repos/filamentphp/support/zipball/e7174cee7e1d08205f7120d0dcc0d00d9bdd4d32", + "reference": "e7174cee7e1d08205f7120d0dcc0d00d9bdd4d32", "shasum": "" }, "require": { @@ -1541,7 +1541,7 @@ "illuminate/support": "^10.45|^11.0", "illuminate/view": "^10.45|^11.0", "kirschbaum-development/eloquent-power-joins": "^3.0|^4.0", - "livewire/livewire": "^3.4.10 <= 3.5.6", + "livewire/livewire": "^3.4.10", "php": "^8.1", "ryangjchandler/blade-capture-directive": "^0.2|^0.3|^1.0", "spatie/color": "^1.5", @@ -1576,20 +1576,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:29+00:00" + "time": "2024-10-31T13:38:25+00:00" }, { "name": "filament/tables", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "152bf46a8f2c46f047835771a67085c2866b039b" + "reference": "56a852f7992a01ad8d7b85034cdbb2ae8a21086a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/152bf46a8f2c46f047835771a67085c2866b039b", - "reference": "152bf46a8f2c46f047835771a67085c2866b039b", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/56a852f7992a01ad8d7b85034cdbb2ae8a21086a", + "reference": "56a852f7992a01ad8d7b85034cdbb2ae8a21086a", "shasum": "" }, "require": { @@ -1628,11 +1628,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:25+00:00" + "time": "2024-10-31T13:38:27+00:00" }, { "name": "filament/widgets", - "version": "v3.2.117", + "version": "v3.2.122", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -1935,16 +1935,16 @@ }, { "name": "guzzlehttp/promises", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8" + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", - "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", "shasum": "" }, "require": { @@ -1998,7 +1998,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.3" + "source": "https://github.com/guzzle/promises/tree/2.0.4" }, "funding": [ { @@ -2014,7 +2014,7 @@ "type": "tidelift" } ], - "time": "2024-07-18T10:29:17+00:00" + "time": "2024-10-17T10:06:22+00:00" }, { "name": "guzzlehttp/psr7", @@ -2283,16 +2283,16 @@ }, { "name": "laravel/fortify", - "version": "v1.24.2", + "version": "v1.24.4", "source": { "type": "git", "url": "https://github.com/laravel/fortify.git", - "reference": "42695c45087e5abb3e173725b4f1ef4956a7b47d" + "reference": "5bd3bdd535acf4054865c64eec6d8bb8c60cc127" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/fortify/zipball/42695c45087e5abb3e173725b4f1ef4956a7b47d", - "reference": "42695c45087e5abb3e173725b4f1ef4956a7b47d", + "url": "https://api.github.com/repos/laravel/fortify/zipball/5bd3bdd535acf4054865c64eec6d8bb8c60cc127", + "reference": "5bd3bdd535acf4054865c64eec6d8bb8c60cc127", "shasum": "" }, "require": { @@ -2344,20 +2344,20 @@ "issues": "https://github.com/laravel/fortify/issues", "source": "https://github.com/laravel/fortify" }, - "time": "2024-09-16T19:20:52+00:00" + "time": "2024-10-29T13:59:23+00:00" }, { "name": "laravel/framework", - "version": "v11.27.2", + "version": "v11.30.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "a51d1f2b771c542324a3d9b76a98b1bbc75c0ee9" + "reference": "dff716442d9c229d716be82ccc9a7de52eb97193" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/a51d1f2b771c542324a3d9b76a98b1bbc75c0ee9", - "reference": "a51d1f2b771c542324a3d9b76a98b1bbc75c0ee9", + "url": "https://api.github.com/repos/laravel/framework/zipball/dff716442d9c229d716be82ccc9a7de52eb97193", + "reference": "dff716442d9c229d716be82ccc9a7de52eb97193", "shasum": "" }, "require": { @@ -2553,25 +2553,25 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-10-09T04:17:35+00:00" + "time": "2024-10-30T15:00:34+00:00" }, { "name": "laravel/prompts", - "version": "v0.1.25", + "version": "v0.3.1", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95" + "reference": "0f3848a445562dac376b27968f753c65e7e1036e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/7b4029a84c37cb2725fc7f011586e2997040bc95", - "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95", + "url": "https://api.github.com/repos/laravel/prompts/zipball/0f3848a445562dac376b27968f753c65e7e1036e", + "reference": "0f3848a445562dac376b27968f753c65e7e1036e", "shasum": "" }, "require": { + "composer-runtime-api": "^2.2", "ext-mbstring": "*", - "illuminate/collections": "^10.0|^11.0", "php": "^8.1", "symfony/console": "^6.2|^7.0" }, @@ -2580,6 +2580,7 @@ "laravel/framework": ">=10.17.0 <10.25.0" }, "require-dev": { + "illuminate/collections": "^10.0|^11.0", "mockery/mockery": "^1.5", "pestphp/pest": "^2.3", "phpstan/phpstan": "^1.11", @@ -2591,7 +2592,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "0.1.x-dev" + "dev-main": "0.3.x-dev" } }, "autoload": { @@ -2609,9 +2610,73 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.1.25" + "source": "https://github.com/laravel/prompts/tree/v0.3.1" }, - "time": "2024-08-12T22:06:33+00:00" + "time": "2024-10-09T19:42:26+00:00" + }, + { + "name": "laravel/sanctum", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "54aea9d13743ae8a6cdd3c28dbef128a17adecab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/54aea9d13743ae8a6cdd3c28dbef128a17adecab", + "reference": "54aea9d13743ae8a6cdd3c28dbef128a17adecab", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/database": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2", + "symfony/console": "^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2024-09-27T14:55:41+00:00" }, { "name": "laravel/serializable-closure", @@ -2930,16 +2995,16 @@ }, { "name": "league/csv", - "version": "9.17.0", + "version": "9.18.0", "source": { "type": "git", "url": "https://github.com/thephpleague/csv.git", - "reference": "8cab815fb11ec93aa2f7b8a57b3daa1f1a364011" + "reference": "b02d010e4055ae992247f6ffd1e7b103ef2a0790" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/csv/zipball/8cab815fb11ec93aa2f7b8a57b3daa1f1a364011", - "reference": "8cab815fb11ec93aa2f7b8a57b3daa1f1a364011", + "url": "https://api.github.com/repos/thephpleague/csv/zipball/b02d010e4055ae992247f6ffd1e7b103ef2a0790", + "reference": "b02d010e4055ae992247f6ffd1e7b103ef2a0790", "shasum": "" }, "require": { @@ -2951,11 +3016,11 @@ "ext-xdebug": "*", "friendsofphp/php-cs-fixer": "^3.64.0", "phpbench/phpbench": "^1.3.1", - "phpstan/phpstan": "^1.12.5", + "phpstan/phpstan": "^1.12.6", "phpstan/phpstan-deprecation-rules": "^1.2.1", "phpstan/phpstan-phpunit": "^1.4.0", "phpstan/phpstan-strict-rules": "^1.6.1", - "phpunit/phpunit": "^10.5.16 || ^11.4.0", + "phpunit/phpunit": "^10.5.16 || ^11.4.1", "symfony/var-dumper": "^6.4.8 || ^7.1.5" }, "suggest": { @@ -3013,7 +3078,7 @@ "type": "github" } ], - "time": "2024-10-10T10:30:28+00:00" + "time": "2024-10-18T08:14:48+00:00" }, { "name": "league/flysystem", @@ -3379,16 +3444,16 @@ }, { "name": "livewire/livewire", - "version": "v3.5.6", + "version": "v3.5.12", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f" + "reference": "3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/597a2808d8d3001cc3ed5ce89a6ebab00f83b80f", - "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f", + "url": "https://api.github.com/repos/livewire/livewire/zipball/3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d", + "reference": "3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d", "shasum": "" }, "require": { @@ -3396,7 +3461,7 @@ "illuminate/routing": "^10.0|^11.0", "illuminate/support": "^10.0|^11.0", "illuminate/validation": "^10.0|^11.0", - "laravel/prompts": "^0.1.24", + "laravel/prompts": "^0.1.24|^0.2|^0.3", "league/mime-type-detection": "^1.9", "php": "^8.1", "symfony/console": "^6.0|^7.0", @@ -3443,7 +3508,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.5.6" + "source": "https://github.com/livewire/livewire/tree/v3.5.12" }, "funding": [ { @@ -3451,7 +3516,7 @@ "type": "github" } ], - "time": "2024-08-19T11:52:18+00:00" + "time": "2024-10-15T19:35:06+00:00" }, { "name": "masterminds/html5", @@ -4001,32 +4066,31 @@ }, { "name": "nunomaduro/termwind", - "version": "v2.1.0", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a" + "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/e5f21eade88689536c0cdad4c3cd75f3ed26e01a", - "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/42c84e4e8090766bbd6445d06cd6e57650626ea3", + "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3", "shasum": "" }, "require": { "ext-mbstring": "*", "php": "^8.2", - "symfony/console": "^7.0.4" + "symfony/console": "^7.1.5" }, "require-dev": { - "ergebnis/phpstan-rules": "^2.2.0", - "illuminate/console": "^11.1.1", - "laravel/pint": "^1.15.0", - "mockery/mockery": "^1.6.11", - "pestphp/pest": "^2.34.6", - "phpstan/phpstan": "^1.10.66", - "phpstan/phpstan-strict-rules": "^1.5.2", - "symfony/var-dumper": "^7.0.4", + "illuminate/console": "^11.28.0", + "laravel/pint": "^1.18.1", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0", + "phpstan/phpstan": "^1.12.6", + "phpstan/phpstan-strict-rules": "^1.6.1", + "symfony/var-dumper": "^7.1.5", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -4069,7 +4133,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.1.0" + "source": "https://github.com/nunomaduro/termwind/tree/v2.2.0" }, "funding": [ { @@ -4085,7 +4149,7 @@ "type": "github" } ], - "time": "2024-09-05T15:25:50+00:00" + "time": "2024-10-15T16:15:16+00:00" }, { "name": "openspout/openspout", @@ -5556,17 +5620,88 @@ "time": "2024-08-27T18:56:10+00:00" }, { - "name": "symfony/clock", - "version": "v7.1.1", + "name": "spatie/laravel-route-attributes", + "version": "1.24.0", "source": { "type": "git", - "url": "https://github.com/symfony/clock.git", - "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7" + "url": "https://github.com/spatie/laravel-route-attributes.git", + "reference": "2dcf83b33a49e39a395127943a06471d93445c84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/3dfc8b084853586de51dd1441c6242c76a28cbe7", - "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7", + "url": "https://api.github.com/repos/spatie/laravel-route-attributes/zipball/2dcf83b33a49e39a395127943a06471d93445c84", + "reference": "2dcf83b33a49e39a395127943a06471d93445c84", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^10.0|^11.0", + "nesbot/carbon": "^2.63|^3.0", + "php": "^8.0" + }, + "require-dev": { + "orchestra/testbench": "^8.0|^9.0", + "phpunit/phpunit": "^9.5.10|^10.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\RouteAttributes\\RouteAttributesServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\RouteAttributes\\": "src", + "Spatie\\RouteAttributes\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Auto register routes using PHP attributes", + "homepage": "https://github.com/spatie/laravel-route-attributes", + "keywords": [ + "laravel-route-attributes", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-route-attributes/issues", + "source": "https://github.com/spatie/laravel-route-attributes/tree/1.24.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2024-10-18T13:36:10+00:00" + }, + { + "name": "symfony/clock", + "version": "v7.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "97bebc53548684c17ed696bc8af016880f0f098d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/97bebc53548684c17ed696bc8af016880f0f098d", + "reference": "97bebc53548684c17ed696bc8af016880f0f098d", "shasum": "" }, "require": { @@ -5611,7 +5746,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.1.1" + "source": "https://github.com/symfony/clock/tree/v7.1.6" }, "funding": [ { @@ -5627,20 +5762,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/console", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" + "reference": "bb5192af6edc797cbab5c8e8ecfea2fe5f421e57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", - "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "url": "https://api.github.com/repos/symfony/console/zipball/bb5192af6edc797cbab5c8e8ecfea2fe5f421e57", + "reference": "bb5192af6edc797cbab5c8e8ecfea2fe5f421e57", "shasum": "" }, "require": { @@ -5704,7 +5839,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.5" + "source": "https://github.com/symfony/console/tree/v7.1.6" }, "funding": [ { @@ -5720,20 +5855,20 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-10-09T08:46:59+00:00" }, { "name": "symfony/css-selector", - "version": "v7.1.1", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4" + "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c7cee86c6f812896af54434f8ce29c8d94f9ff4", - "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/4aa4f6b3d6749c14d3aa815eef8226632e7bbc66", + "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66", "shasum": "" }, "require": { @@ -5769,7 +5904,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.1.1" + "source": "https://github.com/symfony/css-selector/tree/v7.1.6" }, "funding": [ { @@ -5785,7 +5920,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5856,16 +5991,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.1.3", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "432bb369952795c61ca1def65e078c4a80dad13c" + "reference": "d60117093c2a9fe667baa8fedf84e8a09b9c592f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c", - "reference": "432bb369952795c61ca1def65e078c4a80dad13c", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/d60117093c2a9fe667baa8fedf84e8a09b9c592f", + "reference": "d60117093c2a9fe667baa8fedf84e8a09b9c592f", "shasum": "" }, "require": { @@ -5911,7 +6046,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.1.3" + "source": "https://github.com/symfony/error-handler/tree/v7.1.6" }, "funding": [ { @@ -5927,20 +6062,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T13:02:51+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.1.1", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7" + "reference": "87254c78dd50721cfd015b62277a8281c5589702" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", - "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87254c78dd50721cfd015b62277a8281c5589702", + "reference": "87254c78dd50721cfd015b62277a8281c5589702", "shasum": "" }, "require": { @@ -5991,7 +6126,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.6" }, "funding": [ { @@ -6007,7 +6142,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -6087,16 +6222,16 @@ }, { "name": "symfony/finder", - "version": "v7.1.4", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" + "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", + "url": "https://api.github.com/repos/symfony/finder/zipball/2cb89664897be33f78c65d3d2845954c8d7a43b8", + "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8", "shasum": "" }, "require": { @@ -6131,7 +6266,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.4" + "source": "https://github.com/symfony/finder/tree/v7.1.6" }, "funding": [ { @@ -6147,20 +6282,20 @@ "type": "tidelift" } ], - "time": "2024-08-13T14:28:19+00:00" + "time": "2024-10-01T08:31:23+00:00" }, { "name": "symfony/html-sanitizer", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/html-sanitizer.git", - "reference": "89bf376c056926bd7fe8a81c0f486a060e20fdbc" + "reference": "a25620fc6407e14331f3c0c5668eb4f35c392d4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/89bf376c056926bd7fe8a81c0f486a060e20fdbc", - "reference": "89bf376c056926bd7fe8a81c0f486a060e20fdbc", + "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/a25620fc6407e14331f3c0c5668eb4f35c392d4a", + "reference": "a25620fc6407e14331f3c0c5668eb4f35c392d4a", "shasum": "" }, "require": { @@ -6200,7 +6335,7 @@ "sanitizer" ], "support": { - "source": "https://github.com/symfony/html-sanitizer/tree/v7.1.5" + "source": "https://github.com/symfony/html-sanitizer/tree/v7.1.6" }, "funding": [ { @@ -6216,20 +6351,20 @@ "type": "tidelift" } ], - "time": "2024-09-20T13:35:23+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b" + "reference": "3d7bbf071b25f802f7d55524d408bed414ea71e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e30ef73b1e44eea7eb37ba69600a354e553f694b", - "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3d7bbf071b25f802f7d55524d408bed414ea71e2", + "reference": "3d7bbf071b25f802f7d55524d408bed414ea71e2", "shasum": "" }, "require": { @@ -6277,7 +6412,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.5" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.6" }, "funding": [ { @@ -6293,20 +6428,20 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-10-11T19:23:14+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b" + "reference": "5d8315899cd76b2e7e29179bf5fea103e41bdf03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/44204d96150a9df1fc57601ec933d23fefc2d65b", - "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5d8315899cd76b2e7e29179bf5fea103e41bdf03", + "reference": "5d8315899cd76b2e7e29179bf5fea103e41bdf03", "shasum": "" }, "require": { @@ -6391,7 +6526,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.5" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.6" }, "funding": [ { @@ -6407,20 +6542,20 @@ "type": "tidelift" } ], - "time": "2024-09-21T06:09:21+00:00" + "time": "2024-10-27T13:54:21+00:00" }, { "name": "symfony/mailer", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "bbf21460c56f29810da3df3e206e38dfbb01e80b" + "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/bbf21460c56f29810da3df3e206e38dfbb01e80b", - "reference": "bbf21460c56f29810da3df3e206e38dfbb01e80b", + "url": "https://api.github.com/repos/symfony/mailer/zipball/69c9948451fb3a6a4d47dc8261d1794734e76cdd", + "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd", "shasum": "" }, "require": { @@ -6471,7 +6606,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.1.5" + "source": "https://github.com/symfony/mailer/tree/v7.1.6" }, "funding": [ { @@ -6487,20 +6622,20 @@ "type": "tidelift" } ], - "time": "2024-09-08T12:32:26+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/mime", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff" + "reference": "caa1e521edb2650b8470918dfe51708c237f0598" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/711d2e167e8ce65b05aea6b258c449671cdd38ff", - "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff", + "url": "https://api.github.com/repos/symfony/mime/zipball/caa1e521edb2650b8470918dfe51708c237f0598", + "reference": "caa1e521edb2650b8470918dfe51708c237f0598", "shasum": "" }, "require": { @@ -6555,7 +6690,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.5" + "source": "https://github.com/symfony/mime/tree/v7.1.6" }, "funding": [ { @@ -6571,7 +6706,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-10-25T15:11:02+00:00" }, { "name": "symfony/polyfill-ctype", @@ -7211,16 +7346,16 @@ }, { "name": "symfony/process", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "5c03ee6369281177f07f7c68252a280beccba847" + "reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", - "reference": "5c03ee6369281177f07f7c68252a280beccba847", + "url": "https://api.github.com/repos/symfony/process/zipball/6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e", + "reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e", "shasum": "" }, "require": { @@ -7252,7 +7387,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.5" + "source": "https://github.com/symfony/process/tree/v7.1.6" }, "funding": [ { @@ -7268,20 +7403,20 @@ "type": "tidelift" } ], - "time": "2024-09-19T21:48:23+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/routing", - "version": "v7.1.4", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7" + "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", - "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", + "url": "https://api.github.com/repos/symfony/routing/zipball/66a2c469f6c22d08603235c46a20007c0701ea0a", + "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a", "shasum": "" }, "require": { @@ -7333,7 +7468,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.1.4" + "source": "https://github.com/symfony/routing/tree/v7.1.6" }, "funding": [ { @@ -7349,7 +7484,7 @@ "type": "tidelift" } ], - "time": "2024-08-29T08:16:25+00:00" + "time": "2024-10-01T08:31:23+00:00" }, { "name": "symfony/service-contracts", @@ -7436,16 +7571,16 @@ }, { "name": "symfony/string", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" + "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", + "url": "https://api.github.com/repos/symfony/string/zipball/61b72d66bf96c360a727ae6232df5ac83c71f626", + "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626", "shasum": "" }, "require": { @@ -7503,7 +7638,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.5" + "source": "https://github.com/symfony/string/tree/v7.1.6" }, "funding": [ { @@ -7519,20 +7654,20 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/translation", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea" + "reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/235535e3f84f3dfbdbde0208ede6ca75c3a489ea", - "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea", + "url": "https://api.github.com/repos/symfony/translation/zipball/b9f72ab14efdb6b772f85041fa12f820dee8d55f", + "reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f", "shasum": "" }, "require": { @@ -7597,7 +7732,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.1.5" + "source": "https://github.com/symfony/translation/tree/v7.1.6" }, "funding": [ { @@ -7613,7 +7748,7 @@ "type": "tidelift" } ], - "time": "2024-09-16T06:30:38+00:00" + "time": "2024-09-28T12:35:13+00:00" }, { "name": "symfony/translation-contracts", @@ -7695,16 +7830,16 @@ }, { "name": "symfony/uid", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "8c7bb8acb933964055215d89f9a9871df0239317" + "reference": "65befb3bb2d503bbffbd08c815aa38b472999917" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/8c7bb8acb933964055215d89f9a9871df0239317", - "reference": "8c7bb8acb933964055215d89f9a9871df0239317", + "url": "https://api.github.com/repos/symfony/uid/zipball/65befb3bb2d503bbffbd08c815aa38b472999917", + "reference": "65befb3bb2d503bbffbd08c815aa38b472999917", "shasum": "" }, "require": { @@ -7749,7 +7884,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.1.5" + "source": "https://github.com/symfony/uid/tree/v7.1.6" }, "funding": [ { @@ -7765,20 +7900,20 @@ "type": "tidelift" } ], - "time": "2024-09-17T09:16:35+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "e20e03889539fd4e4211e14d2179226c513c010d" + "reference": "cb5bd55a6b8c2c1c7fb68b0aeae0e257948a720c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e20e03889539fd4e4211e14d2179226c513c010d", - "reference": "e20e03889539fd4e4211e14d2179226c513c010d", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cb5bd55a6b8c2c1c7fb68b0aeae0e257948a720c", + "reference": "cb5bd55a6b8c2c1c7fb68b0aeae0e257948a720c", "shasum": "" }, "require": { @@ -7832,7 +7967,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.5" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.6" }, "funding": [ { @@ -7848,7 +7983,7 @@ "type": "tidelift" } ], - "time": "2024-09-16T10:07:02+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -8121,6 +8256,56 @@ } ], "packages-dev": [ + { + "name": "erusev/parsedown", + "version": "1.7.4", + "source": { + "type": "git", + "url": "https://github.com/erusev/parsedown.git", + "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3", + "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35" + }, + "type": "library", + "autoload": { + "psr-0": { + "Parsedown": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", + "keywords": [ + "markdown", + "parser" + ], + "support": { + "issues": "https://github.com/erusev/parsedown/issues", + "source": "https://github.com/erusev/parsedown/tree/1.7.x" + }, + "time": "2019-12-30T22:54:17+00:00" + }, { "name": "fakerphp/faker", "version": "v1.23.1", @@ -8306,6 +8491,101 @@ }, "time": "2020-07-09T08:09:16+00:00" }, + { + "name": "knuckleswtf/scribe", + "version": "4.38.0", + "source": { + "type": "git", + "url": "https://github.com/knuckleswtf/scribe.git", + "reference": "da667aafb6804b4b599ac6506bb178bfa5434802" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/knuckleswtf/scribe/zipball/da667aafb6804b4b599ac6506bb178bfa5434802", + "reference": "da667aafb6804b4b599ac6506bb178bfa5434802", + "shasum": "" + }, + "require": { + "erusev/parsedown": "1.7.4", + "ext-fileinfo": "*", + "ext-json": "*", + "ext-pdo": "*", + "fakerphp/faker": "^1.9.1", + "illuminate/console": "^8.0|^9.0|^10.0|^11.0", + "illuminate/routing": "^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0", + "league/flysystem": "^1.1.4|^2.1.1|^3.0", + "mpociot/reflection-docblock": "^1.0.1", + "nikic/php-parser": "^5.0", + "nunomaduro/collision": "^5.10|^6.0|^7.0|^8.0", + "php": ">=8.0", + "ramsey/uuid": "^4.2.2", + "shalvah/clara": "^3.1.0", + "shalvah/upgrader": ">=0.6.0", + "spatie/data-transfer-object": "^2.6|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "replace": { + "mpociot/laravel-apidoc-generator": "*" + }, + "require-dev": { + "brianium/paratest": "^6.0", + "dms/phpunit-arraysubset-asserts": "^0.4", + "laravel/legacy-factories": "^1.3.0", + "laravel/lumen-framework": "^8.0|^9.0|^10.0", + "league/fractal": "^0.20", + "nikic/fast-route": "^1.3", + "orchestra/testbench": "^6.0|^7.0|^8.0", + "pestphp/pest": "^1.21", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^9.0|^10.0", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dom-crawler": "^5.4|^6.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Knuckles\\Scribe\\ScribeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Knuckles\\Camel\\": "camel/", + "Knuckles\\Scribe\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Shalvah" + } + ], + "description": "Generate API documentation for humans from your Laravel codebase.✍", + "homepage": "http://github.com/knuckleswtf/scribe", + "keywords": [ + "api", + "dingo", + "documentation", + "laravel" + ], + "support": { + "issues": "https://github.com/knuckleswtf/scribe/issues", + "source": "https://github.com/knuckleswtf/scribe/tree/4.38.0" + }, + "funding": [ + { + "url": "https://patreon.com/shalvah", + "type": "patreon" + } + ], + "time": "2024-10-18T20:16:40+00:00" + }, { "name": "laradumps/laradumps", "version": "v3.2.0", @@ -8380,16 +8660,16 @@ }, { "name": "laradumps/laradumps-core", - "version": "v2.3.0", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/laradumps/laradumps-core.git", - "reference": "e6743a9c5df8effd5e722863292d5d153341b779" + "reference": "71895cad1a8d54502b71308c829f5265a662bf3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laradumps/laradumps-core/zipball/e6743a9c5df8effd5e722863292d5d153341b779", - "reference": "e6743a9c5df8effd5e722863292d5d153341b779", + "url": "https://api.github.com/repos/laradumps/laradumps-core/zipball/71895cad1a8d54502b71308c829f5265a662bf3b", + "reference": "71895cad1a8d54502b71308c829f5265a662bf3b", "shasum": "" }, "require": { @@ -8437,7 +8717,7 @@ "homepage": "https://github.com/laradumps/laradumps-core", "support": { "issues": "https://github.com/laradumps/laradumps-core/issues", - "source": "https://github.com/laradumps/laradumps-core/tree/v2.3.0" + "source": "https://github.com/laradumps/laradumps-core/tree/v2.3.1" }, "funding": [ { @@ -8445,7 +8725,7 @@ "type": "github" } ], - "time": "2024-09-20T16:37:56+00:00" + "time": "2024-10-16T20:33:49+00:00" }, { "name": "laravel/pint", @@ -8515,16 +8795,16 @@ }, { "name": "laravel/sail", - "version": "v1.35.0", + "version": "v1.37.1", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "992bc2d9e52174c79515967f30849d21daa334d8" + "reference": "7efa151ea0d16f48233d6a6cd69f81270acc6e93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/992bc2d9e52174c79515967f30849d21daa334d8", - "reference": "992bc2d9e52174c79515967f30849d21daa334d8", + "url": "https://api.github.com/repos/laravel/sail/zipball/7efa151ea0d16f48233d6a6cd69f81270acc6e93", + "reference": "7efa151ea0d16f48233d6a6cd69f81270acc6e93", "shasum": "" }, "require": { @@ -8574,7 +8854,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2024-10-08T14:45:26+00:00" + "time": "2024-10-29T20:18:14+00:00" }, { "name": "mockery/mockery", @@ -8659,6 +8939,59 @@ }, "time": "2024-05-16T03:13:13+00:00" }, + { + "name": "mpociot/reflection-docblock", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/mpociot/reflection-docblock.git", + "reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpociot/reflection-docblock/zipball/c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587", + "reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mpociot": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "support": { + "issues": "https://github.com/mpociot/reflection-docblock/issues", + "source": "https://github.com/mpociot/reflection-docblock/tree/master" + }, + "time": "2016-06-20T20:53:12+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.12.0", @@ -8721,23 +9054,23 @@ }, { "name": "nunomaduro/collision", - "version": "v8.4.0", + "version": "v8.5.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a" + "reference": "f5c101b929c958e849a633283adff296ed5f38f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/e7d1aa8ed753f63fa816932bbc89678238843b4a", - "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5", "shasum": "" }, "require": { - "filp/whoops": "^2.15.4", - "nunomaduro/termwind": "^2.0.1", + "filp/whoops": "^2.16.0", + "nunomaduro/termwind": "^2.1.0", "php": "^8.2.0", - "symfony/console": "^7.1.3" + "symfony/console": "^7.1.5" }, "conflict": { "laravel/framework": "<11.0.0 || >=12.0.0", @@ -8745,14 +9078,14 @@ }, "require-dev": { "larastan/larastan": "^2.9.8", - "laravel/framework": "^11.19.0", - "laravel/pint": "^1.17.1", - "laravel/sail": "^1.31.0", - "laravel/sanctum": "^4.0.2", - "laravel/tinker": "^2.9.0", - "orchestra/testbench-core": "^9.2.3", - "pestphp/pest": "^2.35.0 || ^3.0.0", - "sebastian/environment": "^6.1.0 || ^7.0.0" + "laravel/framework": "^11.28.0", + "laravel/pint": "^1.18.1", + "laravel/sail": "^1.36.0", + "laravel/sanctum": "^4.0.3", + "laravel/tinker": "^2.10.0", + "orchestra/testbench-core": "^9.5.3", + "pestphp/pest": "^2.36.0 || ^3.4.0", + "sebastian/environment": "^6.1.0 || ^7.2.0" }, "type": "library", "extra": { @@ -8814,7 +9147,7 @@ "type": "patreon" } ], - "time": "2024-08-03T15:32:23+00:00" + "time": "2024-10-15T16:06:32+00:00" }, { "name": "phar-io/manifest", @@ -9257,16 +9590,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.36", + "version": "10.5.38", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "aa0a8ce701ea7ee314b0dfaa8970dc94f3f8c870" + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/aa0a8ce701ea7ee314b0dfaa8970dc94f3f8c870", - "reference": "aa0a8ce701ea7ee314b0dfaa8970dc94f3f8c870", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", "shasum": "" }, "require": { @@ -9287,7 +9620,7 @@ "phpunit/php-timer": "^6.0.0", "sebastian/cli-parser": "^2.0.1", "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.2", + "sebastian/comparator": "^5.0.3", "sebastian/diff": "^5.1.1", "sebastian/environment": "^6.1.0", "sebastian/exporter": "^5.1.2", @@ -9338,7 +9671,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.36" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38" }, "funding": [ { @@ -9354,7 +9687,7 @@ "type": "tidelift" } ], - "time": "2024-10-08T15:36:51+00:00" + "time": "2024-10-28T13:06:21+00:00" }, { "name": "sebastian/cli-parser", @@ -9526,16 +9859,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { @@ -9546,7 +9879,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.4" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -9591,7 +9924,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -9599,7 +9932,7 @@ "type": "github" } ], - "time": "2024-08-12T06:03:08+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", @@ -10272,6 +10605,111 @@ ], "time": "2023-02-07T11:34:05+00:00" }, + { + "name": "shalvah/clara", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/shalvah/clara.git", + "reference": "cdbb5737cbdd101756d97dd2279a979a1af7710b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/shalvah/clara/zipball/cdbb5737cbdd101756d97dd2279a979a1af7710b", + "reference": "cdbb5737cbdd101756d97dd2279a979a1af7710b", + "shasum": "" + }, + "require": { + "php": ">=7.4", + "symfony/console": "^4.0|^5.0|^6.0|^7.0" + }, + "require-dev": { + "eloquent/phony-phpunit": "^7.0", + "phpunit/phpunit": "^9.1" + }, + "type": "library", + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Shalvah\\Clara\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "🔊 Simple, pretty, testable console output for CLI apps.", + "keywords": [ + "cli", + "log", + "logging" + ], + "support": { + "issues": "https://github.com/shalvah/clara/issues", + "source": "https://github.com/shalvah/clara/tree/3.2.0" + }, + "time": "2024-02-27T20:30:59+00:00" + }, + { + "name": "shalvah/upgrader", + "version": "0.6.0", + "source": { + "type": "git", + "url": "https://github.com/shalvah/upgrader.git", + "reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/shalvah/upgrader/zipball/d95ed17fe9f5e1ee7d47ad835595f1af080a867f", + "reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f", + "shasum": "" + }, + "require": { + "illuminate/support": ">=8.0", + "nikic/php-parser": "^5.0", + "php": ">=8.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.0", + "pestphp/pest": "^1.21", + "phpstan/phpstan": "^1.0", + "spatie/ray": "^1.33" + }, + "type": "library", + "autoload": { + "psr-4": { + "Shalvah\\Upgrader\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Shalvah", + "email": "hello@shalvah.me" + } + ], + "description": "Create automatic upgrades for your package.", + "homepage": "http://github.com/shalvah/upgrader", + "keywords": [ + "upgrade" + ], + "support": { + "issues": "https://github.com/shalvah/upgrader/issues", + "source": "https://github.com/shalvah/upgrader/tree/0.6.0" + }, + "funding": [ + { + "url": "https://patreon.com/shalvah", + "type": "patreon" + } + ], + "time": "2024-02-20T11:51:46+00:00" + }, { "name": "spatie/backtrace", "version": "1.6.2", @@ -10335,6 +10773,70 @@ ], "time": "2024-07-22T08:21:24+00:00" }, + { + "name": "spatie/data-transfer-object", + "version": "3.9.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/data-transfer-object.git", + "reference": "1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8", + "reference": "1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "illuminate/collections": "^8.36", + "jetbrains/phpstorm-attributes": "^1.0", + "larapack/dd": "^1.1", + "phpunit/phpunit": "^9.5.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\DataTransferObject\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brent Roose", + "email": "brent@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Data transfer objects with batteries included", + "homepage": "https://github.com/spatie/data-transfer-object", + "keywords": [ + "data-transfer-object", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/data-transfer-object/issues", + "source": "https://github.com/spatie/data-transfer-object/tree/3.9.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "abandoned": "spatie/laravel-data", + "time": "2022-09-16T13:34:38+00:00" + }, { "name": "spatie/error-solutions", "version": "1.1.1", @@ -10653,17 +11155,93 @@ "time": "2024-06-12T15:01:18+00:00" }, { - "name": "symfony/yaml", - "version": "v7.1.5", + "name": "symfony/var-exporter", + "version": "v7.1.6", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4" + "url": "https://github.com/symfony/var-exporter.git", + "reference": "90173ef89c40e7c8c616653241048705f84130ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4e561c316e135e053bd758bf3b3eb291d9919de4", - "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/90173ef89c40e7c8c616653241048705f84130ef", + "reference": "90173ef89c40e7c8c616653241048705f84130ef", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v7.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3ced3f29e4f0d6bce2170ff26719f1fe9aacc671", + "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671", "shasum": "" }, "require": { @@ -10705,7 +11283,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.5" + "source": "https://github.com/symfony/yaml/tree/v7.1.6" }, "funding": [ { @@ -10721,7 +11299,7 @@ "type": "tidelift" } ], - "time": "2024-09-17T12:49:58+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "theseer/tokenizer", diff --git a/config/route-attributes.php b/config/route-attributes.php new file mode 100644 index 0000000..3356c39 --- /dev/null +++ b/config/route-attributes.php @@ -0,0 +1,47 @@ + true, + + /* + * Controllers in these directories that have routing attributes + * will automatically be registered. + * + * Optionally, you can specify group configuration by using key/values + */ + 'directories' => [ + app_path('Http/Controllers') => [ + 'prefix' => '', + 'middleware' => 'web', + 'patterns' => ['*Controller.php'], + 'not_patterns' => ['API/*'], + ], + app_path('Http/Controllers/API') => [ + 'prefix' => '', + 'middleware' => 'api', + 'patterns' => ['*Controller.php'], + 'not_patterns' => [], + ], + ], + + /* + * This middleware will be applied to all routes. + */ + 'middleware' => [ + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + + /* + * When enabled, implicitly scoped bindings will be enabled by default. + * You can override this behaviour by using the `ScopeBindings` attribute, and passing `false` to it. + * + * Possible values: + * - null: use the default behaviour + * - true: enable implicitly scoped bindings for all routes + * - false: disable implicitly scoped bindings for all routes + */ + 'scope-bindings' => null, +]; diff --git a/config/scribe.php b/config/scribe.php new file mode 100644 index 0000000..4d44ddb --- /dev/null +++ b/config/scribe.php @@ -0,0 +1,274 @@ + for the generated documentation. If this is empty, Scribe will infer it from config('app.name'). + 'title' => 'API Documentation', + + // A short description of your API. Will be included in the docs webpage, Postman collection and OpenAPI spec. + 'description' => 'VitoDeploy\'s API documentation.', + + // The base URL displayed in the docs. If this is empty, Scribe will use the value of config('app.url') at generation time. + // If you're using `laravel` type, you can set this to a dynamic string, like '{{ config("app.tenant_url") }}' to get a dynamic base URL. + 'base_url' => 'https://your-vito-url', + + 'routes' => [ + [ + // Routes that match these conditions will be included in the docs + 'match' => [ + // Match only routes whose paths match this pattern (use * as a wildcard to match any characters). Example: 'users/*'. + 'prefixes' => ['api/*'], + + // Match only routes whose domains match this pattern (use * as a wildcard to match any characters). Example: 'api.*'. + 'domains' => ['*'], + + // [Dingo router only] Match only routes registered under this version. Wildcards are NOT supported. + 'versions' => ['v1'], + ], + + // Include these routes even if they did not match the rules above. + 'include' => [ + // 'users.index', 'POST /new', '/auth/*' + ], + + // Exclude these routes even if they matched the rules above. + 'exclude' => [ + 'api.git-hooks', + 'api.servers.agent', + ], + ], + ], + + // The type of documentation output to generate. + // - "static" will generate a static HTMl page in the /public/docs folder, + // - "laravel" will generate the documentation as a Blade view, so you can add routing and authentication. + // - "external_static" and "external_laravel" do the same as above, but generate a basic template, + // passing the OpenAPI spec as a URL, allowing you to easily use the docs with an external generator + 'type' => 'static', + + // See https://scribe.knuckles.wtf/laravel/reference/config#theme for supported options + 'theme' => 'default', + + 'static' => [ + // HTML documentation, assets and Postman collection will be generated to this folder. + // Source Markdown will still be in resources/docs. + 'output_path' => 'public/api-docs', + + 'url' => '/api-docs/index.html', + ], + + 'laravel' => [ + // Whether to automatically create a docs endpoint for you to view your generated docs. + // If this is false, you can still set up routing manually. + 'add_routes' => false, + + // URL path to use for the docs endpoint (if `add_routes` is true). + // By default, `/docs` opens the HTML page, `/docs.postman` opens the Postman collection, and `/docs.openapi` the OpenAPI spec. + 'docs_url' => '/api-docs', + + // Directory within `public` in which to store CSS and JS assets. + // By default, assets are stored in `public/vendor/scribe`. + // If set, assets will be stored in `public/{{assets_directory}}` + 'assets_directory' => null, + + // Middleware to attach to the docs endpoint (if `add_routes` is true). + 'middleware' => [], + ], + + 'external' => [ + 'html_attributes' => [], + ], + + 'try_it_out' => [ + // Add a Try It Out button to your endpoints so consumers can test endpoints right from their browser. + // Don't forget to enable CORS headers for your endpoints. + 'enabled' => true, + + // The base URL for the API tester to use (for example, you can set this to your staging URL). + // Leave as null to use the current app URL when generating (config("app.url")). + 'base_url' => null, + + // [Laravel Sanctum] Fetch a CSRF token before each request, and add it as an X-XSRF-TOKEN header. + 'use_csrf' => false, + + // The URL to fetch the CSRF token from (if `use_csrf` is true). + 'csrf_url' => '/sanctum/csrf-cookie', + ], + + // How is your API authenticated? This information will be used in the displayed docs, generated examples and response calls. + 'auth' => [ + // Set this to true if ANY endpoints in your API use authentication. + 'enabled' => true, + + // Set this to true if your API should be authenticated by default. If so, you must also set `enabled` (above) to true. + // You can then use @unauthenticated or @authenticated on individual endpoints to change their status from the default. + 'default' => true, + + // Where is the auth value meant to be sent in a request? + // Options: query, body, basic, bearer, header (for custom header) + 'in' => 'bearer', + + // The name of the auth parameter (eg token, key, apiKey) or header (eg Authorization, Api-Key). + 'name' => 'key', + + // The value of the parameter to be used by Scribe to authenticate response calls. + // This will NOT be included in the generated documentation. If empty, Scribe will use a random value. + 'use_value' => '', + + // Placeholder your users will see for the auth parameter in the example requests. + // Set this to null if you want Scribe to use a random value as placeholder instead. + 'placeholder' => env('SCRIBE_AUTH_KEY', 'YOUR_API_KEY'), + + // Any extra authentication-related info for your users. Markdown and HTML are supported. + 'extra_info' => 'You can retrieve your token by visiting here', + ], + + // Text to place in the "Introduction" section, right after the `description`. Markdown and HTML are supported. + 'intro_text' => <<<'INTRO' +This documentation aims to provide all the information you need to work with our API. + + +INTRO + , + + // Example requests for each endpoint will be shown in each of these languages. + // Supported options are: bash, javascript, php, python + // To add a language of your own, see https://scribe.knuckles.wtf/laravel/advanced/example-requests + 'example_languages' => [ + 'bash', + 'php', + 'javascript', + ], + + // Generate a Postman collection (v2.1.0) in addition to HTML docs. + // For 'static' docs, the collection will be generated to public/docs/collection.json. + // For 'laravel' docs, it will be generated to storage/app/scribe/collection.json. + // Setting `laravel.add_routes` to true (above) will also add a route for the collection. + 'postman' => [ + 'enabled' => true, + + 'overrides' => [ + // 'info.version' => '2.0.0', + ], + ], + + // Generate an OpenAPI spec (v3.0.1) in addition to docs webpage. + // For 'static' docs, the collection will be generated to public/docs/openapi.yaml. + // For 'laravel' docs, it will be generated to storage/app/scribe/openapi.yaml. + // Setting `laravel.add_routes` to true (above) will also add a route for the spec. + 'openapi' => [ + 'enabled' => true, + + 'overrides' => [ + // 'info.version' => '2.0.0', + ], + ], + + 'groups' => [ + // Endpoints which don't have a @group will be placed in this default group. + 'default' => 'Endpoints', + + // By default, Scribe will sort groups alphabetically, and endpoints in the order their routes are defined. + // You can override this by listing the groups, subgroups and endpoints here in the order you want them. + // See https://scribe.knuckles.wtf/blog/laravel-v4#easier-sorting and https://scribe.knuckles.wtf/laravel/reference/config#order for details + 'order' => [], + ], + + // Custom logo path. This will be used as the value of the src attribute for the tag, + // so make sure it points to an accessible URL or path. Set to false to not use a logo. + // For example, if your logo is in public/img: + // - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs) + // - 'logo' => 'img/logo.png' // for `laravel` type + 'logo' => false, + + // Customize the "Last updated" value displayed in the docs by specifying tokens and formats. + // Examples: + // - {date:F j Y} => March 28, 2022 + // - {git:short} => Short hash of the last Git commit + // Available tokens are `{date:}` and `{git:}`. + // The format you pass to `date` will be passed to PHP's `date()` function. + // The format you pass to `git` can be either "short" or "long". + 'last_updated' => 'Last updated: {date:F j, Y}', + + 'examples' => [ + // Set this to any number (eg. 1234) to generate the same example values for parameters on each run, + 'faker_seed' => null, + + // With API resources and transformers, Scribe tries to generate example models to use in your API responses. + // By default, Scribe will try the model's factory, and if that fails, try fetching the first from the database. + // You can reorder or remove strategies here. + 'models_source' => ['factoryCreate', 'factoryMake', 'databaseFirst'], + ], + + // The strategies Scribe will use to extract information about your routes at each stage. + // If you create or install a custom strategy, add it here. + 'strategies' => [ + 'metadata' => [ + Strategies\Metadata\GetFromDocBlocks::class, + Strategies\Metadata\GetFromMetadataAttributes::class, + ], + 'urlParameters' => [ + Strategies\UrlParameters\GetFromLaravelAPI::class, + Strategies\UrlParameters\GetFromUrlParamAttribute::class, + Strategies\UrlParameters\GetFromUrlParamTag::class, + ], + 'queryParameters' => [ + Strategies\QueryParameters\GetFromFormRequest::class, + Strategies\QueryParameters\GetFromInlineValidator::class, + Strategies\QueryParameters\GetFromQueryParamAttribute::class, + Strategies\QueryParameters\GetFromQueryParamTag::class, + ], + 'headers' => [ + Strategies\Headers\GetFromHeaderAttribute::class, + Strategies\Headers\GetFromHeaderTag::class, + [ + 'override', + [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ], + ], + ], + 'bodyParameters' => [ + Strategies\BodyParameters\GetFromFormRequest::class, + Strategies\BodyParameters\GetFromInlineValidator::class, + Strategies\BodyParameters\GetFromBodyParamAttribute::class, + Strategies\BodyParameters\GetFromBodyParamTag::class, + ], + 'responses' => [ + Strategies\Responses\UseResponseAttributes::class, + Strategies\Responses\UseTransformerTags::class, + Strategies\Responses\UseApiResourceTags::class, + Strategies\Responses\UseResponseTag::class, + Strategies\Responses\UseResponseFileTag::class, + [ + Strategies\Responses\ResponseCalls::class, + [ + 'only' => ['GET *'], + // Disable debug mode when generating response calls to avoid error stack traces in responses + 'config' => [ + 'app.debug' => false, + ], + ], + ], + ], + 'responseFields' => [ + Strategies\ResponseFields\GetFromResponseFieldAttribute::class, + Strategies\ResponseFields\GetFromResponseFieldTag::class, + ], + ], + + // For response calls, API resource responses and transformer responses, + // Scribe will try to start database transactions, so no changes are persisted to your database. + // Tell Scribe which connections should be transacted here. If you only use one db connection, you can leave this as is. + 'database_connections_to_transact' => [config('database.default')], + + 'fractal' => [ + // If you are using a custom serializer with league/fractal, you can specify it here. + 'serializer' => null, + ], + + 'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::class, +]; diff --git a/database/factories/SourceControlFactory.php b/database/factories/SourceControlFactory.php index 0844ef9..45c09d5 100644 --- a/database/factories/SourceControlFactory.php +++ b/database/factories/SourceControlFactory.php @@ -14,6 +14,7 @@ public function definition(): array { return [ 'access_token' => Str::random(10), + 'provider' => \App\Enums\SourceControl::GITHUB, 'profile' => $this->faker->name, 'project_id' => null, ]; diff --git a/public/api-docs/collection.json b/public/api-docs/collection.json new file mode 100644 index 0000000..9ad91e1 --- /dev/null +++ b/public/api-docs/collection.json @@ -0,0 +1,2898 @@ +{ + "variable": [ + { + "id": "baseUrl", + "key": "baseUrl", + "type": "string", + "name": "string", + "value": "https:\/\/your-vito-url" + } + ], + "info": { + "name": "API Documentation", + "_postman_id": "a41cda01-38ef-4ec3-8538-037284060387", + "description": "VitoDeploy's API documentation.", + "schema": "https:\/\/schema.getpostman.com\/json\/collection\/v2.1.0\/collection.json" + }, + "item": [ + { + "name": "cron-jobs", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/cron-jobs", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/cron-jobs", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all cron jobs." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"server_id\":null,\"command\":\"ls -la\",\"user\":\"root\",\"frequency\":\"* * * * *\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null},{\"id\":null,\"server_id\":null,\"command\":\"ls -la\",\"user\":\"root\",\"frequency\":\"* * * * *\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/cron-jobs", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/cron-jobs", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"command\":\"qui\",\"user\":\"root\",\"frequency\":\"* * * * *\"}" + }, + "description": "Create a new cron job." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"command\":\"ls -la\",\"user\":\"root\",\"frequency\":\"* * * * *\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/cron-jobs\/:cronJob_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/cron-jobs\/:cronJob_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "cronJob_id", + "key": "cronJob_id", + "value": "5", + "description": "The ID of the cronJob." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a cron job by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"command\":\"ls -la\",\"user\":\"root\",\"frequency\":\"* * * * *\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/cron-jobs\/:cronJob_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/cron-jobs\/:cronJob_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "cronJob_id", + "key": "cronJob_id", + "value": "5", + "description": "The ID of the cronJob." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete cron job." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "database-users", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/database-users", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/database-users", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all database users." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"server_id\":null,\"username\":\"nyasia68\",\"databases\":[],\"host\":\"%\",\"status\":null,\"created_at\":null,\"updated_at\":null},{\"id\":null,\"server_id\":null,\"username\":\"madyson20\",\"databases\":[],\"host\":\"%\",\"status\":null,\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/database-users", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/database-users", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"username\":\"dignissimos\",\"password\":\"OK+XEG2)\",\"host\":\"%\"}" + }, + "description": "Create a new database user." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"username\":\"amya.nitzsche\",\"databases\":[],\"host\":\"%\",\"status\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/database-users\/:databaseUser_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/database-users\/:databaseUser_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "databaseUser_id", + "key": "databaseUser_id", + "value": "4", + "description": "The ID of the databaseUser." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a database user by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"username\":\"bergstrom.ericka\",\"databases\":[],\"host\":\"%\",\"status\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "link", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/database-users\/:databaseUser_id\/link", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/database-users\/:databaseUser_id\/link", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "databaseUser_id", + "key": "databaseUser_id", + "value": "4", + "description": "The ID of the databaseUser." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"databases\":\"accusantium\"}" + }, + "description": "Link to databases" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"username\":\"fmurray\",\"databases\":[],\"host\":\"%\",\"status\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/database-users\/:databaseUser_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/database-users\/:databaseUser_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "databaseUser_id", + "key": "databaseUser_id", + "value": "4", + "description": "The ID of the databaseUser." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete database user." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "databases", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/databases", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/databases", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all databases." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"server_id\":null,\"name\":\"clockman\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null},{\"id\":null,\"server_id\":null,\"name\":\"wvonrueden\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/databases", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/databases", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":\"nesciunt\"}" + }, + "description": "Create a new database." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"name\":\"johanna76\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/databases\/:id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/databases\/:id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "id", + "key": "id", + "value": "6", + "description": "The ID of the database." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a database by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"name\":\"chloe.huel\",\"status\":\"ready\",\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/databases\/:database_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/databases\/:database_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "database_id", + "key": "database_id", + "value": "6", + "description": "The ID of the database." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete database." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "firewall-rules", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/firewall-rules", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/firewall-rules", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all firewall rules." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"server_id\":null,\"type\":\"allow\",\"protocol\":\"tcp\",\"port\":18074,\"source\":\"189.27.156.82\",\"mask\":24,\"note\":\"test\",\"status\":null,\"created_at\":null,\"updated_at\":null},{\"id\":null,\"server_id\":null,\"type\":\"allow\",\"protocol\":\"tcp\",\"port\":41088,\"source\":\"86.177.121.87\",\"mask\":24,\"note\":\"test\",\"status\":null,\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/firewall-rules", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/firewall-rules", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"type\":\"allow\",\"protocol\":\"udp\",\"port\":\"voluptates\",\"source\":\"saepe\",\"mask\":\"0\"}" + }, + "description": "Create a new firewall rule." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"type\":\"allow\",\"protocol\":\"tcp\",\"port\":61992,\"source\":\"47.222.76.48\",\"mask\":24,\"note\":\"test\",\"status\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/firewall-rules\/:firewallRule_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/firewall-rules\/:firewallRule_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "firewallRule_id", + "key": "firewallRule_id", + "value": "7", + "description": "The ID of the firewallRule." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a firewall rule by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"type\":\"allow\",\"protocol\":\"tcp\",\"port\":43107,\"source\":\"135.73.216.16\",\"mask\":24,\"note\":\"test\",\"status\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/firewall-rules\/:firewallRule_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/firewall-rules\/:firewallRule_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "firewallRule_id", + "key": "firewallRule_id", + "value": "7", + "description": "The ID of the firewallRule." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete firewall rule." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "general", + "description": "", + "item": [ + { + "name": "health-check", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/health", + "query": [], + "raw": "{{baseUrl}}\/api\/health" + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "", + "auth": { + "type": "noauth" + } + }, + "response": [ + { + "header": [ + { + "key": "cache-control", + "value": "no-cache, private" + }, + { + "key": "content-type", + "value": "application\/json" + }, + { + "key": "x-ratelimit-limit", + "value": "60" + }, + { + "key": "x-ratelimit-remaining", + "value": "59" + }, + { + "key": "access-control-allow-origin", + "value": "*" + } + ], + "code": 200, + "body": "{\"success\":true,\"version\":\"2.0.0\"}", + "name": "" + } + ] + } + ] + }, + { + "name": "projects", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects", + "query": [], + "raw": "{{baseUrl}}\/api\/projects" + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all projects." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":29,\"name\":\"Zachary Lueilwitz\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"},{\"id\":30,\"name\":\"Mrs. Kiarra Heller IV\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects", + "query": [], + "raw": "{{baseUrl}}\/api\/projects" + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":\"quos\"}" + }, + "description": "Create a new project." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":29,\"name\":\"Hershel Spinka\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:id", + "variable": [ + { + "id": "id", + "key": "id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a project by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":29,\"name\":\"Emery Kiehn\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "update", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:id", + "variable": [ + { + "id": "id", + "key": "id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":\"ut\"}" + }, + "description": "Update project." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":29,\"name\":\"Mable Prohaska\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete project." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "server-providers", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/server-providers", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/server-providers", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":2,\"project_id\":null,\"global\":true,\"name\":\"dolor\",\"provider\":\"digitalocean\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"},{\"id\":3,\"project_id\":null,\"global\":true,\"name\":\"enim\",\"provider\":\"digitalocean\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/server-providers", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/server-providers", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"provider\":\"autem\",\"name\":\"enim\",\"token\":\"culpa\",\"key\":\"sit\",\"secret\":\"voluptates\"}" + }, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":2,\"project_id\":null,\"global\":true,\"name\":\"eligendi\",\"provider\":\"aws\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/server-providers\/:serverProvider_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/server-providers\/:serverProvider_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "serverProvider_id", + "key": "serverProvider_id", + "value": "1", + "description": "The ID of the serverProvider." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":2,\"project_id\":null,\"global\":true,\"name\":\"architecto\",\"provider\":\"digitalocean\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "update", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/server-providers\/:serverProvider_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/server-providers\/:serverProvider_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "serverProvider_id", + "key": "serverProvider_id", + "value": "1", + "description": "The ID of the serverProvider." + } + ] + }, + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":\"minus\",\"global\":false}" + }, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":2,\"project_id\":null,\"global\":true,\"name\":\"reiciendis\",\"provider\":\"hetzner\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/server-providers\/:serverProvider_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/server-providers\/:serverProvider_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "serverProvider_id", + "key": "serverProvider_id", + "value": "1", + "description": "The ID of the serverProvider." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "servers", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all servers in a project." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"project_id\":null,\"user_id\":null,\"provider_id\":null,\"name\":\"Dorthy Toy\",\"ssh_user\":\"vito\",\"ip\":\"172.132.95.155\",\"local_ip\":\"118.57.197.65\",\"port\":22,\"os\":\"ubuntu_22\",\"type\":\"regular\",\"type_data\":null,\"provider\":\"custom\",\"provider_data\":null,\"public_key\":\"test\",\"status\":\"ready\",\"auto_update\":null,\"available_updates\":0,\"security_updates\":null,\"progress\":100,\"progress_step\":null,\"updates\":null,\"last_update_check\":null,\"created_at\":null,\"updated_at\":null},{\"id\":null,\"project_id\":null,\"user_id\":null,\"provider_id\":null,\"name\":\"Carrie Sporer\",\"ssh_user\":\"vito\",\"ip\":\"184.242.162.173\",\"local_ip\":\"135.244.50.22\",\"port\":22,\"os\":\"ubuntu_22\",\"type\":\"regular\",\"type_data\":null,\"provider\":\"custom\",\"provider_data\":null,\"public_key\":\"test\",\"status\":\"ready\",\"auto_update\":null,\"available_updates\":0,\"security_updates\":null,\"progress\":100,\"progress_step\":null,\"updates\":null,\"last_update_check\":null,\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"provider\":\"et\",\"server_provider\":\"digitalocean\",\"region\":\"inventore\",\"plan\":\"atque\",\"ip\":\"quam\",\"port\":\"nemo\",\"name\":\"perspiciatis\",\"os\":\"similique\",\"type\":\"regular\",\"webserver\":\"none\",\"database\":\"none\",\"php\":\"8.1\"}" + }, + "description": "Create a new server." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"project_id\":null,\"user_id\":null,\"provider_id\":null,\"name\":\"Flo Beer PhD\",\"ssh_user\":\"vito\",\"ip\":\"168.238.14.230\",\"local_ip\":\"40.232.73.41\",\"port\":22,\"os\":\"ubuntu_22\",\"type\":\"regular\",\"type_data\":null,\"provider\":\"custom\",\"provider_data\":null,\"public_key\":\"test\",\"status\":\"ready\",\"auto_update\":null,\"available_updates\":0,\"security_updates\":null,\"progress\":100,\"progress_step\":null,\"updates\":null,\"last_update_check\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "id", + "key": "id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a server by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"project_id\":null,\"user_id\":null,\"provider_id\":null,\"name\":\"Stephany Ankunding\",\"ssh_user\":\"vito\",\"ip\":\"145.28.94.46\",\"local_ip\":\"69.133.44.100\",\"port\":22,\"os\":\"ubuntu_22\",\"type\":\"regular\",\"type_data\":null,\"provider\":\"custom\",\"provider_data\":null,\"public_key\":\"test\",\"status\":\"ready\",\"auto_update\":null,\"available_updates\":0,\"security_updates\":null,\"progress\":100,\"progress_step\":null,\"updates\":null,\"last_update_check\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "reboot", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/reboot", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/reboot", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Reboot a server." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + }, + { + "name": "upgrade", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/upgrade", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/upgrade", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Upgrade server." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete server." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "services", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all services." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"server_id\":null,\"type\":null,\"type_data\":null,\"name\":null,\"version\":null,\"unit\":null,\"status\":null,\"is_default\":null,\"created_at\":null,\"updated_at\":null},{\"id\":null,\"server_id\":null,\"type\":null,\"type_data\":null,\"name\":null,\"version\":null,\"unit\":null,\"status\":null,\"is_default\":null,\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services\/:id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services\/:id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "id", + "key": "id", + "value": "27", + "description": "The ID of the service." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a service by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"type\":null,\"type_data\":null,\"name\":null,\"version\":null,\"unit\":null,\"status\":null,\"is_default\":null,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "start", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/start", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/start", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "service_id", + "key": "service_id", + "value": "27", + "description": "The ID of the service." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Start service." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + }, + { + "name": "stop", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/stop", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/stop", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "service_id", + "key": "service_id", + "value": "27", + "description": "The ID of the service." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Stop service." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + }, + { + "name": "restart", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/restart", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/restart", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "service_id", + "key": "service_id", + "value": "27", + "description": "The ID of the service." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Restart service." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + }, + { + "name": "enable", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/enable", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/enable", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "service_id", + "key": "service_id", + "value": "27", + "description": "The ID of the service." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Enable service." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + }, + { + "name": "disable", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/disable", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id\/disable", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "service_id", + "key": "service_id", + "value": "27", + "description": "The ID of the service." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Disable service." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/services\/:service_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "service_id", + "key": "service_id", + "value": "27", + "description": "The ID of the service." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete service." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "sites", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/sites", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/sites", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all sites." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"server_id\":null,\"source_control_id\":null,\"type\":\"laravel\",\"type_data\":null,\"domain\":\"test.com\",\"aliases\":null,\"web_directory\":\"\\\/\",\"path\":\"\\\/home\",\"php_version\":\"8.2\",\"repository\":null,\"branch\":\"main\",\"status\":\"ready\",\"port\":null,\"progress\":100,\"created_at\":null,\"updated_at\":null},{\"id\":null,\"server_id\":null,\"source_control_id\":null,\"type\":\"laravel\",\"type_data\":null,\"domain\":\"test.com\",\"aliases\":null,\"web_directory\":\"\\\/\",\"path\":\"\\\/home\",\"php_version\":\"8.2\",\"repository\":null,\"branch\":\"main\",\"status\":\"ready\",\"port\":null,\"progress\":100,\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/sites", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/sites", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"type\":\"wordpress\",\"domain\":\"quo\",\"aliases\":[\"dolorum\"],\"php_version\":\"7.4\",\"web_directory\":\"public\",\"source_control\":\"explicabo\",\"repository\":\"organization\\\/repository\",\"branch\":\"main\",\"composer\":true,\"version\":\"5.2.1\"}" + }, + "description": "Create a new site." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"source_control_id\":null,\"type\":\"laravel\",\"type_data\":null,\"domain\":\"test.com\",\"aliases\":null,\"web_directory\":\"\\\/\",\"path\":\"\\\/home\",\"php_version\":\"8.2\",\"repository\":null,\"branch\":\"main\",\"status\":\"ready\",\"port\":null,\"progress\":100,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/sites\/:id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/sites\/:id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "id", + "key": "id", + "value": "8", + "description": "The ID of the site." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get a site by ID." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"server_id\":null,\"source_control_id\":null,\"type\":\"laravel\",\"type_data\":null,\"domain\":\"test.com\",\"aliases\":null,\"web_directory\":\"\\\/\",\"path\":\"\\\/home\",\"php_version\":\"8.2\",\"repository\":null,\"branch\":\"main\",\"status\":\"ready\",\"port\":null,\"progress\":100,\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/sites\/:site_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/sites\/:site_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "site_id", + "key": "site_id", + "value": "8", + "description": "The ID of the site." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete site." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "source-controls", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/source-controls", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/source-controls", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":5,\"project_id\":null,\"global\":true,\"name\":\"Jaiden Kling\",\"provider\":\"github\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"},{\"id\":6,\"project_id\":null,\"global\":true,\"name\":\"Ms. Brianne Bosco\",\"provider\":\"github\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/source-controls", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/source-controls", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"provider\":\"bitbucket\",\"name\":\"eos\",\"token\":\"et\",\"url\":\"https:\\\/\\\/lueilwitz.com\\\/nostrum-et-porro-atque-sint.html\",\"username\":\"consectetur\",\"password\":\"PL.P?{06\\\\ECi0\"}" + }, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":5,\"project_id\":null,\"global\":true,\"name\":\"Toby Parker\",\"provider\":\"github\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/source-controls\/:sourceControl_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/source-controls\/:sourceControl_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "sourceControl_id", + "key": "sourceControl_id", + "value": "3", + "description": "The ID of the sourceControl." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":5,\"project_id\":null,\"global\":true,\"name\":\"Prof. Bartholome Graham IV\",\"provider\":\"github\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "update", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/source-controls\/:sourceControl_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/source-controls\/:sourceControl_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "sourceControl_id", + "key": "sourceControl_id", + "value": "3", + "description": "The ID of the sourceControl." + } + ] + }, + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":\"quaerat\",\"token\":\"consectetur\",\"url\":\"http:\\\/\\\/www.hudson.biz\\\/rerum-voluptatem-debitis-accusamus\",\"username\":\"voluptatem\",\"password\":\"\\\\p\\\/el>)3#~E?kI\",\"global\":false}" + }, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":5,\"project_id\":null,\"global\":true,\"name\":\"Cicero Smitham\",\"provider\":\"github\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/source-controls\/:sourceControl_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/source-controls\/:sourceControl_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "sourceControl_id", + "key": "sourceControl_id", + "value": "3", + "description": "The ID of the sourceControl." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "ssh-keys", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/ssh-keys", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/ssh-keys", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Get all ssh keys." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":null,\"user\":null,\"name\":\"Dr. Reanna Braun\",\"created_at\":null,\"updated_at\":null},{\"id\":null,\"user\":null,\"name\":\"Norene Fritsch\",\"created_at\":null,\"updated_at\":null}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/ssh-keys", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/ssh-keys", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"key_id\":\"vero\",\"name\":\"voluptates\",\"public_key\":\"dolor\"}" + }, + "description": "Deploy ssh key to server." + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":null,\"user\":null,\"name\":\"Sophia D'Amore\",\"created_at\":null,\"updated_at\":null}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/servers\/:server_id\/ssh-keys\/:sshKey_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/servers\/:server_id\/ssh-keys\/:sshKey_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "server_id", + "key": "server_id", + "value": "3", + "description": "The ID of the server." + }, + { + "id": "sshKey_id", + "key": "sshKey_id", + "value": "4", + "description": "The ID of the sshKey." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "Delete ssh key from server." + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + }, + { + "name": "storage-providers", + "description": "", + "item": [ + { + "name": "list", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/storage-providers", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/storage-providers", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"data\":[{\"id\":3,\"project_id\":null,\"global\":true,\"name\":\"et\",\"provider\":\"local\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"},{\"id\":4,\"project_id\":null,\"global\":true,\"name\":\"sed\",\"provider\":\"local\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}],\"links\":{\"first\":\"\\\/?page=1\",\"last\":\"\\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"« Previous\",\"active\":false},{\"url\":\"\\\/?page=1\",\"label\":\"1\",\"active\":true},{\"url\":null,\"label\":\"Next »\",\"active\":false}],\"path\":\"\\\/\",\"per_page\":25,\"to\":2,\"total\":2}}", + "name": "" + } + ] + }, + { + "name": "create", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/storage-providers", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/storage-providers", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"provider\":\"quod\",\"name\":\"commodi\",\"token\":\"ipsum\",\"key\":\"ratione\",\"secret\":\"iste\"}" + }, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":3,\"project_id\":null,\"global\":true,\"name\":\"est\",\"provider\":\"dropbox\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "show", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/storage-providers\/:storageProvider_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/storage-providers\/:storageProvider_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "storageProvider_id", + "key": "storageProvider_id", + "value": "1", + "description": "The ID of the storageProvider." + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":3,\"project_id\":null,\"global\":true,\"name\":\"officia\",\"provider\":\"ftp\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "update", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/storage-providers\/:storageProvider_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/storage-providers\/:storageProvider_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "storageProvider_id", + "key": "storageProvider_id", + "value": "1", + "description": "The ID of the storageProvider." + } + ] + }, + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":\"iusto\",\"global\":true}" + }, + "description": "" + }, + "response": [ + { + "header": [], + "code": 200, + "body": "{\"id\":3,\"project_id\":null,\"global\":true,\"name\":\"rerum\",\"provider\":\"ftp\",\"created_at\":\"2024-11-01T15:40:48.000000Z\",\"updated_at\":\"2024-11-01T15:40:48.000000Z\"}", + "name": "" + } + ] + }, + { + "name": "delete", + "request": { + "url": { + "host": "{{baseUrl}}", + "path": "api\/projects\/:project_id\/storage-providers\/:storageProvider_id", + "query": [], + "raw": "{{baseUrl}}\/api\/projects\/:project_id\/storage-providers\/:storageProvider_id", + "variable": [ + { + "id": "project_id", + "key": "project_id", + "value": "1", + "description": "The ID of the project." + }, + { + "id": "storageProvider_id", + "key": "storageProvider_id", + "value": "1", + "description": "The ID of the storageProvider." + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application\/json" + }, + { + "key": "Accept", + "value": "application\/json" + } + ], + "body": null, + "description": "" + }, + "response": [ + { + "header": [], + "code": 204, + "body": "null", + "name": "" + } + ] + } + ] + } + ], + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "key", + "type": "string" + } + ] + } +} \ No newline at end of file diff --git a/public/api-docs/css/theme-default.print.css b/public/api-docs/css/theme-default.print.css new file mode 100644 index 0000000..18ab760 --- /dev/null +++ b/public/api-docs/css/theme-default.print.css @@ -0,0 +1,393 @@ +/* Copied from https://github.com/slatedocs/slate/blob/c4b4c0b8f83e891ca9fab6bbe9a1a88d5fe41292/stylesheets/print.css and unminified */ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100% +} + +body { + margin: 0 +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block +} + +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline +} + +audio:not([controls]) { + display: none; + height: 0 +} + +[hidden], +template { + display: none +} + +a { + background-color: transparent +} + +a:active, +a:hover { + outline: 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, +strong { + font-weight: bold +} + +dfn { + font-style: italic +} + +h1 { + font-size: 2em; + margin: 0.67em 0 +} + +mark { + background: #ff0; + color: #000 +} + +small { + font-size: 80% +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -0.5em +} + +sub { + bottom: -0.25em +} + +img { + border: 0 +} + +svg:not(:root) { + overflow: hidden +} + +figure { + margin: 1em 40px +} + +hr { + box-sizing: content-box; + height: 0 +} + +pre { + overflow: auto +} + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em +} + +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0 +} + +button { + overflow: visible +} + +button, +select { + text-transform: none +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer +} + +button[disabled], +html input[disabled] { + cursor: default +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0 +} + +input { + line-height: normal +} + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0 +} + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto +} + +input[type="search"] { + -webkit-appearance: textfield; + box-sizing: content-box +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none +} + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em +} + +legend { + border: 0; + padding: 0 +} + +textarea { + overflow: auto +} + +optgroup { + font-weight: bold +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +td, +th { + padding: 0 +} + +.content h1, +.content h2, +.content h3, +.content h4, +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 14px +} + +.content h1, +.content h2, +.content h3, +.content h4 { + font-weight: bold +} + +.content pre, +.content code { + font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif; + font-size: 12px; + line-height: 1.5 +} + +.content pre, +.content code { + word-break: break-all; + -webkit-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto +} + +@font-face { + font-family: 'slate'; + src: url(../fonts/slate.eot?-syv14m); + src: url(../fonts/slate.eot?#iefix-syv14m) format("embedded-opentype"), url(../fonts/slate.woff2?-syv14m) format("woff2"), url(../fonts/slate.woff?-syv14m) format("woff"), url(../fonts/slate.ttf?-syv14m) format("truetype"), url(../fonts/slate.svg?-syv14m#slate) format("svg"); + font-weight: normal; + font-style: normal +} + +.content aside.warning:before, +.content aside.notice:before, +.content aside.success:before { + font-family: 'slate'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1 +} + +.content aside.warning:before { + content: "\e600" +} + +.content aside.notice:before { + content: "\e602" +} + +.content aside.success:before { + content: "\e606" +} + +.tocify, +.toc-footer, +.lang-selector, +.search, +#nav-button { + display: none +} + +.tocify-wrapper>img { + margin: 0 auto; + display: block +} + +.content { + font-size: 12px +} + +.content pre, +.content code { + border: 1px solid #999; + border-radius: 5px; + font-size: 0.8em +} + +.content pre code { + border: 0 +} + +.content pre { + padding: 1.3em +} + +.content code { + padding: 0.2em +} + +.content table { + border: 1px solid #999 +} + +.content table tr { + border-bottom: 1px solid #999 +} + +.content table td, +.content table th { + padding: 0.7em +} + +.content p { + line-height: 1.5 +} + +.content a { + text-decoration: none; + color: #000 +} + +.content h1 { + font-size: 2.5em; + padding-top: 0.5em; + padding-bottom: 0.5em; + margin-top: 1em; + margin-bottom: 21px; + border: 2px solid #ccc; + border-width: 2px 0; + text-align: center +} + +.content h2 { + font-size: 1.8em; + margin-top: 2em; + border-top: 2px solid #ccc; + padding-top: 0.8em +} + +.content h1+h2, +.content h1+div+h2 { + border-top: none; + padding-top: 0; + margin-top: 0 +} + +.content h3, +.content h4 { + font-size: 0.8em; + margin-top: 1.5em; + margin-bottom: 0.8em; + text-transform: uppercase +} + +.content h5, +.content h6 { + text-transform: uppercase +} + +.content aside { + padding: 1em; + border: 1px solid #ccc; + border-radius: 5px; + margin-top: 1.5em; + margin-bottom: 1.5em; + line-height: 1.6 +} + +.content aside:before { + vertical-align: middle; + padding-right: 0.5em; + font-size: 14px +} diff --git a/public/api-docs/css/theme-default.style.css b/public/api-docs/css/theme-default.style.css new file mode 100644 index 0000000..9a4741c --- /dev/null +++ b/public/api-docs/css/theme-default.style.css @@ -0,0 +1,1090 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +html { + font-family: 'Open Sans', sans-serif; + font-size: 1.2em; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100% +} + +body { + margin: 0 +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section { + display: block +} + +summary { + cursor: pointer; +} + +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline +} + +audio:not([controls]) { + display: none; + height: 0 +} + +[hidden], +template { + display: none +} + +a { + background-color: transparent +} + +a:active, +a:hover { + outline: 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, +strong { + font-weight: 700 +} + +dfn { + font-style: italic +} + +h1 { + font-size: 2em; + margin: .67em 0 +} + +mark { + background: #ff0; + color: #000 +} + +small { + font-size: 80% +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -.5em +} + +sub { + bottom: -.25em +} + +img { + border: 0 +} + +svg:not(:root) { + overflow: hidden +} + +figure { + margin: 1em 40px +} + +hr { + box-sizing: content-box; + height: 0 +} + +pre { + overflow: auto +} + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em +} + +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0 +} + +button { + overflow: visible +} + +button, +select { + text-transform: none +} + +button, +html input[type=button], +input[type=reset], +input[type=submit] { + -webkit-appearance: button; + cursor: pointer +} + +button[disabled], +html input[disabled] { + cursor: default +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0 +} + +input { + line-height: normal +} + +input[type=checkbox], +input[type=radio] { + box-sizing: border-box; + padding: 0 +} + +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + height: auto +} + +input[type=search] { + -webkit-appearance: textfield; + box-sizing: content-box +} + +input[type=search]::-webkit-search-cancel-button, +input[type=search]::-webkit-search-decoration { + -webkit-appearance: none +} + +fieldset { + border: 1px solid silver; + margin: 0 2px; + padding: .35em .625em .75em +} + +legend { + border: 0; + padding: 0 +} + +textarea { + overflow: auto +} + +optgroup { + font-weight: 700 +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +td, +th { + padding: 0 +} + +body, +html { + font-family: 'Open Sans', Helvetica Neue, Helvetica, Arial, Microsoft Yahei, 微软雅黑, STXihei, 华文细黑, sans-serif; + font-size: 16px; +} + +.content h1, +.content h2, +.content h3, +.content h4, +.content h5, +.content h6 { + font-family: 'Open Sans', Helvetica Neue, Helvetica, Arial, Microsoft Yahei, 微软雅黑, STXihei, 华文细黑, sans-serif; +} + +.content h1, +.content h2, +.content h3, +.content h4, +.content h5, +.content h6 { + font-weight: 700 +} + +.content code, +.content pre { + font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif; + font-size: 14px; + line-height: 1.5 +} + +.content code { + word-break: break-all; + word-break: break-word; + -webkit-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto +} + +.content aside.notice:before, +.content aside.success:before, +.content aside.warning:before, +.tocify-wrapper>.search:before { + font-family: 'Open Sans', sans-serif; + speak: none; + font-style: normal; + font-variant: normal; + text-transform: none; + line-height: 1 +} + +.content aside.warning:before { + content: "✋" +} + +.content aside.notice:before { + content: "ℹ" +} + +.content aside.success:before { + content: "✅" +} + +.tocify-wrapper>.search:before { + content: "🔎" +} + +.highlight .c, +.highlight .c1, +.highlight .cm, +.highlight .cs { + color: #909090 +} + +.highlight, +.highlight .w { + background-color: #292929 +} + +.hljs { + display: block; + overflow-x: auto; + padding: .5em; + background: #23241f +} + +.hljs, +.hljs-subst, +.hljs-tag { + color: #f8f8f2 +} + +.hljs-emphasis, +.hljs-strong { + color: #a8a8a2 +} + +.hljs-bullet, +.hljs-link, +.hljs-literal, +.hljs-number, +.hljs-quote, +.hljs-regexp { + color: #ae81ff +} + +.hljs-code, +.hljs-section, +.hljs-selector-class, +.hljs-title { + color: #a6e22e +} + +.hljs-strong { + font-weight: 700 +} + +.hljs-emphasis { + font-style: italic +} + +.hljs-attr, +.hljs-keyword, +.hljs-name, +.hljs-selector-tag { + color: #f92672 +} + +.hljs-attribute, +.hljs-symbol { + color: #66d9ef +} + +.hljs-class .hljs-title, +.hljs-params { + color: #f8f8f2 +} + +.hljs-addition, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-attr, +.hljs-selector-id, +.hljs-selector-pseudo, +.hljs-string, +.hljs-template-variable, +.hljs-type, +.hljs-variable { + color: #e6db74 +} + +.hljs-comment, +.hljs-deletion, +.hljs-meta { + color: #75715e +} + +body, +html { + color: #333; + padding: 0; + margin: 0; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background-color: whitesmoke; + height: 100%; + -webkit-text-size-adjust: none +} + +#toc>ul>li>a>span { + float: right; + background-color: #2484ff; + border-radius: 40px; + width: 20px +} + +.tocify-wrapper { + transition: left .3s ease-in-out; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + z-index: 30; + top: 0; + left: 0; + bottom: 0; + width: 230px; + background-color: #393939; + font-size: 13px; + font-weight: 700 +} + +.tocify-wrapper .lang-selector { + display: none +} + +.tocify-wrapper .lang-selector a { + padding-top: .5em; + padding-bottom: .5em +} + +.tocify-wrapper>img { + display: block +} + +.tocify-wrapper>.search { + position: relative +} + +.tocify-wrapper>.search input { + background: #393939; + border-width: 0 0 1px; + border-color: #666; + padding: 6px 0 6px 20px; + box-sizing: border-box; + margin: 10px 15px; + width: 200px; + outline: none; + color: #fff; + border-radius: 0 +} + +.tocify-wrapper>.search:before { + position: absolute; + top: 17px; + left: 15px; + color: #fff +} + +.tocify-wrapper img+.tocify { + margin-top: 20px +} + +.tocify-wrapper .search-results { + margin-top: 0; + box-sizing: border-box; + height: 0; + overflow-y: auto; + overflow-x: hidden; + transition-property: height, margin; + transition-duration: .18s; + transition-timing-function: ease-in-out; + background: linear-gradient(180deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(0deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(180deg, #000, transparent 1.5px), linear-gradient(0deg, #939393, hsla(0, 0%, 58%, 0) 1.5px), #262626 +} + +.tocify-wrapper .search-results.visible { + height: 30%; + margin-bottom: 1em +} + +.tocify-wrapper .search-results li { + margin: 1em 15px; + line-height: 1 +} + +.tocify-wrapper a { + color: #fff; + text-decoration: none +} + +.tocify-wrapper .search-results a:hover { + text-decoration: underline +} + +.tocify-wrapper .toc-footer li, +.tocify-wrapper .tocify-item>a { + padding: 0 15px; + display: block; + overflow-x: hidden; + white-space: nowrap; + text-overflow: ellipsis +} +.tocify-wrapper .tocify-item.level-3>a { + padding: 0 25px; +} + +.tocify-wrapper li, +.tocify-wrapper ul { + list-style: none; + margin: 0; + padding: 0; + line-height: 28px +} + +.tocify-wrapper li { + color: #fff; + transition-property: background; + transition-timing-function: linear; + transition-duration: .23s +} + +.tocify-wrapper .tocify-focus { + box-shadow: 0 1px 0 #000; + background-color: #2467af; + color: #fff; + font-weight: bold; +} + +.tocify-wrapper .tocify-subheader { + display: none; + background-color: #262626; + font-weight: 500; + background: linear-gradient(180deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(0deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(180deg, #000, transparent 1.5px), linear-gradient(0deg, #939393, hsla(0, 0%, 58%, 0) 1.5px), #262626 +} + +.tocify-wrapper .jets-searching .tocify-subheader, +.tocify-wrapper .tocify-subheader.visible { + display: block; +} + +.tocify-wrapper .tocify-subheader .tocify-item>a { + padding-left: 25px; + font-size: 12px +} + +.tocify-wrapper .tocify-subheader .tocify-item.level-3>a { + padding-left: 35px; +} + +.tocify-wrapper .tocify-subheader>li:last-child { + box-shadow: none +} + +.tocify-wrapper .toc-footer { + padding: 1em 0; + margin-top: 1em; + border-top: 1px dashed #666 +} + +.tocify-wrapper .toc-footer a, +.tocify-wrapper .toc-footer li { + color: #fff; + text-decoration: none +} + +.tocify-wrapper .toc-footer a:hover { + text-decoration: underline +} + +.tocify-wrapper .toc-footer li { + font-size: .8em; + line-height: 1.7; + text-decoration: none +} + +#nav-button { + padding: 0 1.5em 5em 0; + display: none; + position: fixed; + top: 0; + left: 0; + z-index: 100; + color: #000; + text-decoration: none; + font-weight: 700; + opacity: .7; + line-height: 16px; + transition: left .3s ease-in-out +} + +#nav-button span { + display: block; + padding: 6px; + background-color: rgba(234, 242, 246, .7); + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: rotate(-90deg) translate(-100%); + transform: rotate(-90deg) translate(-100%); + border-radius: 0 0 0 5px +} + +#nav-button img { + height: 16px; + vertical-align: bottom +} + +#nav-button:hover { + opacity: 1 +} + +#nav-button.open { + left: 230px +} + +.page-wrapper { + margin-left: 230px; + position: relative; + z-index: 10; + background-color: #eaf2f6; + min-height: 100%; + padding-bottom: 1px +} + +.page-wrapper .dark-box { + width: 50%; + background-color: #393939; + position: absolute; + right: 0; + top: 0; + bottom: 0 +} + +.page-wrapper .lang-selector { + position: fixed; + z-index: 50; + border-bottom: 5px solid #393939 +} + +.lang-selector { + background-color: #222; + width: 100%; + font-weight: 700 +} + +.lang-selector button { + display: block; + float: left; + color: #fff; + text-decoration: none; + padding: 0 10px; + line-height: 30px; + outline: 0; + background: transparent; + border: none; +} + +.lang-selector button:active, +.lang-selector button:hover, +.lang-selector button:focus { + background-color: #111; + color: #fff +} + +.lang-selector button.active { + background-color: #393939; + color: #fff +} + +.lang-selector:after { + content: ''; + clear: both; + display: block +} + +.content { + position: relative; + z-index: 30 +} + +.content:after { + content: ''; + display: block; + clear: both +} + +.content>aside, +.content>details, +.content>dl, +.content>h1, +.content>h2, +.content>h3, +.content>h4, +.content>h5, +.content>h6, +.content>ol, +.content>p, +.content>table, +.content>ul, +.content>div, +.content>form>aside, +.content>form>details, +.content>form>h1, +.content>form>h2, +.content>form>h3, +.content>form>h4, +.content>form>h5, +.content>form>h6, +.content>form>p, +.content>form>table, +.content>form>ul, +.content>form>div { + margin-right: 50%; + padding: 0 28px; + box-sizing: border-box; + display: block; + text-shadow: 0 1px 0 #fff +} + +.content>ol, +.content>ul { + padding-left: 43px +} + +.content>div, +.content>h1, +.content>h2 { + clear: both +} + +.content h1 { + font-size: 30px; + padding-top: .5em; + padding-bottom: .5em; + border-bottom: 1px solid #ccc; + margin-bottom: 21px; + margin-top: 2em; + border-top: 1px solid #ddd; + background-image: linear-gradient(180deg, #fff, #f9f9f9) +} + +.content div:first-child+h1, +.content h1:first-child { + border-top-width: 0; + margin-top: 0 +} + +.content h2 { + font-size: 20px; + margin-top: 4em; + margin-bottom: 0; + border-top: 1px solid #ccc; + padding-top: 1.2em; + padding-bottom: 1.2em; + background-image: linear-gradient(180deg, hsla(0, 0%, 100%, .4), hsla(0, 0%, 100%, 0)) +} + +.content h1+div+h2, +.content h1+h2 { + margin-top: -21px; + border-top: none +} + +.content h3, +.content h4, +.content h5, +.content h6 { + font-size: 15px; + margin-top: 2.5em; + margin-bottom: .8em +} + +.content h4, +.content h5, +.content h6 { + font-size: 10px +} + +.content hr { + margin: 2em 0; + border-top: 2px solid #393939; + border-bottom: 2px solid #eaf2f6 +} + +.content table { + margin-bottom: 1em; + overflow: auto +} + +.content table td, +.content table th { + text-align: left; + vertical-align: top; + line-height: 1.6 +} + +.content table th { + padding: 5px 10px; + border-bottom: 1px solid #ccc; + vertical-align: bottom +} + +.content table td { + padding: 10px +} + +.content table tr:last-child { + border-bottom: 1px solid #ccc +} + +.content table tr:nth-child(odd)>td { + background-color: #ebf3f6 +} + +.content table tr:nth-child(even)>td { + background-color: #ebf2f6 +} + +.content dt { + font-weight: 700 +} + +.content dd { + margin-left: 15px +} + +.content dd, +.content dt, +.content li, +.content p { + line-height: 1.6; + margin-top: 0 +} + +.content img { + max-width: 100% +} + +.content code { + padding: 3px; + border-radius: 3px +} + +.content pre>code { + background-color: transparent; + padding: 0 +} + +.content aside { + padding-top: 1em; + padding-bottom: 1em; + margin-top: 1.5em; + margin-bottom: 1.5em; + background: #292929; + line-height: 1.6; + color: #c8c8c8; + text-shadow: none; +} + +.content aside.info { + background: #8fbcd4; + text-shadow: 0 1px 0 #a0c6da; + color: initial; +} + +.content aside.warning { + background-color: #c97a7e; + text-shadow: 0 1px 0 #d18e91; + color: initial; +} + +.content aside.success { + background-color: #6ac174; + text-shadow: 0 1px 0 #80ca89; + color: initial; +} + +.content aside:before { + vertical-align: middle; + padding-right: .5em; + font-size: 14px +} + +.content .search-highlight { + padding: 2px; + margin: -2px; + border-radius: 4px; + border: 1px solid #f7e633; + text-shadow: 1px 1px 0 #666; + background: linear-gradient(to top left, #f7e633, #f1d32f) +} + +.content blockquote, +.content pre { + background-color: #292929; + color: #fff; + padding: 1.5em 28px; + margin: 0; + width: 50%; + float: right; + clear: right; + box-sizing: border-box; + text-shadow: 0 1px 2px rgba(0, 0, 0, .4) +} + +.content blockquote pre.sf-dump, +.content pre pre.sf-dump { + width: 100%; +} + +.content .annotation { + background-color: #292929; + color: #fff; + padding: 0 28px; + margin: 0; + width: 50%; + float: right; + clear: right; + box-sizing: border-box; + text-shadow: 0 1px 2px rgba(0, 0, 0, .4) +} + +.content .annotation pre { + padding: 0 0; + width: 100%; + float: none; +} + +.content blockquote>p, +.content pre>p { + margin: 0 +} + +.content blockquote a, +.content pre a { + color: #fff; + text-decoration: none; + border-bottom: 1px dashed #ccc +} + +.content blockquote>p { + background-color: #1c1c1c; + border-radius: 5px; + padding: 13px; + color: #ccc; + border-top: 1px solid #000; + border-bottom: 1px solid #404040 +} + +@media (max-width:930px) { + .tocify-wrapper { + left: -230px + } + .tocify-wrapper.open { + left: 0 + } + .page-wrapper { + margin-left: 0 + } + #nav-button { + display: block + } + .tocify-wrapper .tocify-item>a { + padding-top: .3em; + padding-bottom: .3em + } +} + +@media (max-width:700px) { + .dark-box { + display: none + } + .tocify-wrapper .lang-selector { + display: block + } + .page-wrapper .lang-selector { + display: none + } + .content>aside, + .content>details, + .content>dl, + .content>h1, + .content>h2, + .content>h3, + .content>h4, + .content>h5, + .content>h6, + .content>ol, + .content>p, + .content>table, + .content>ul, + .content>div, + .content>form>aside, + .content>form>details, + .content>form>h1, + .content>form>h2, + .content>form>h3, + .content>form>h4, + .content>form>h5, + .content>form>h6, + .content>form>p, + .content>form>table, + .content>form>ul, + .content>form>div { + margin-right: 0; + } + .content blockquote, + .content pre { + float: none; + width: auto + } + .content .annotation { + float: none; + width: auto + } +} + +.badge { + padding: 1px 9px 2px; + white-space: nowrap; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; + color: #ffffff; + text-shadow: none !important; + font-weight: bold; +} + +.badge.badge-darkred { + background-color: darkred; +} + +.badge.badge-red { + background-color: red; +} + +.badge.badge-blue { + background-color: blue; +} + +.badge.badge-darkblue { + background-color: darkblue; +} + +.badge.badge-green { + background-color: green; +} + +.badge.badge-darkgreen { + background-color: darkgreen; +} + +.badge.badge-purple { + background-color: purple; +} + +.badge.badge-black { + background-color: black; +} + +.badge.badge-grey { + background-color: grey; +} + +.fancy-heading-panel { + background-color: lightgrey; + border-radius: 5px; + padding-left: 5px !important; + padding-top: 5px !important; + padding-bottom: 5px !important; + margin-left: 25px; + margin-right: 10px; + width: 47%; +} + +@media screen and (max-width: 700px) { + .fancy-heading-panel { + width: 95%; + } + +} + +button { + border: none; +} + +* { + /* Foreground, Background */ + scrollbar-color: #3c4c67 transparent; +} +*::-webkit-scrollbar { /* Background */ + width: 10px; + height: 10px; + background: transparent; +} + +*::-webkit-scrollbar-thumb { /* Foreground */ + background: #626161; +} diff --git a/public/api-docs/images/navbar.png b/public/api-docs/images/navbar.png new file mode 100644 index 0000000000000000000000000000000000000000..df38e90d87e1a215371b4977e18cde90f8832537 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW*PVQ%R6tFatx` + + + + + + API Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + MENU + navbar-image + + +
+ +
+ + + +
+ + + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+

Introduction

+

VitoDeploy's API documentation.

+ +

This documentation aims to provide all the information you need to work with our API.

+ + +

Authenticating requests

+

To authenticate requests, include an Authorization header with the value "Bearer YOUR-API-KEY".

+

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

+

You can retrieve your token by visiting here

+ +

cron-jobs

+ + + +

list

+ +

+requires authentication +

+ +

Get all cron jobs.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/cron-jobs" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/cron-jobs';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/cron-jobs"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "server_id": null,
+            "command": "ls -la",
+            "user": "root",
+            "frequency": "* * * * *",
+            "status": "ready",
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "server_id": null,
+            "command": "ls -la",
+            "user": "root",
+            "frequency": "* * * * *",
+            "status": "ready",
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/cron-jobs +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

create

+ +

+requires authentication +

+ +

Create a new cron job.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/cron-jobs" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"command\": \"qui\",
+    \"user\": \"root\",
+    \"frequency\": \"* * * * *\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/cron-jobs';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'command' => 'qui',
+            'user' => 'root',
+            'frequency' => '* * * * *',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/cron-jobs"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "command": "qui",
+    "user": "root",
+    "frequency": "* * * * *"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "command": "ls -la",
+    "user": "root",
+    "frequency": "* * * * *",
+    "status": "ready",
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/cron-jobs +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+

Body Parameters

+
+ command   +string  +   + +
+

Example: qui

+
+
+ user   +string  +   + +
+

Example: root

+Must be one of: +
  • root
  • vito
+
+
+ frequency   +string  +   + +
+

Frequency of the cron job. Example: * * * * *

+
+
+ +

show

+ +

+requires authentication +

+ +

Get a cron job by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/cron-jobs/5" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/cron-jobs/5';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/cron-jobs/5"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "command": "ls -la",
+    "user": "root",
+    "frequency": "* * * * *",
+    "status": "ready",
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/cron-jobs/{cronJob_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ cronJob_id   +integer  +   + +
+

The ID of the cronJob. Example: 5

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete cron job.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3/cron-jobs/5" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/cron-jobs/5';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/cron-jobs/5"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id}/cron-jobs/{cronJob_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ cronJob_id   +integer  +   + +
+

The ID of the cronJob. Example: 5

+
+
+ +

database-users

+ + + +

list

+ +

+requires authentication +

+ +

Get all database users.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/database-users" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/database-users';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/database-users"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "server_id": null,
+            "username": "nyasia68",
+            "databases": [],
+            "host": "%",
+            "status": null,
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "server_id": null,
+            "username": "madyson20",
+            "databases": [],
+            "host": "%",
+            "status": null,
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/database-users +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

create

+ +

+requires authentication +

+ +

Create a new database user.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/database-users" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"username\": \"dignissimos\",
+    \"password\": \"OK+XEG2)\",
+    \"host\": \"%\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/database-users';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'username' => 'dignissimos',
+            'password' => 'OK+XEG2)',
+            'host' => '%',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/database-users"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "username": "dignissimos",
+    "password": "OK+XEG2)",
+    "host": "%"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "username": "amya.nitzsche",
+    "databases": [],
+    "host": "%",
+    "status": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/database-users +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+

Body Parameters

+
+ username   +string  +   + +
+

Example: dignissimos

+
+
+ password   +string  +   + +
+

Example: OK+XEG2)

+
+
+ host   +string  +   + +
+

Host, if it is a remote user. Example: %

+
+
+ +

show

+ +

+requires authentication +

+ +

Get a database user by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/database-users/4" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/database-users/4';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/database-users/4"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "username": "bergstrom.ericka",
+    "databases": [],
+    "host": "%",
+    "status": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ databaseUser_id   +integer  +   + +
+

The ID of the databaseUser. Example: 4

+
+
+ + + +

+requires authentication +

+ +

Link to databases

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/database-users/4/link" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"databases\": \"accusantium\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/database-users/4/link';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'databases' => 'accusantium',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/database-users/4/link"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "databases": "accusantium"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "username": "fmurray",
+    "databases": [],
+    "host": "%",
+    "status": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + + + +

delete

+ +

+requires authentication +

+ +

Delete database user.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3/database-users/4" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/database-users/4';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/database-users/4"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ databaseUser_id   +integer  +   + +
+

The ID of the databaseUser. Example: 4

+
+
+ +

databases

+ + + +

list

+ +

+requires authentication +

+ +

Get all databases.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/databases" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/databases';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/databases"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "server_id": null,
+            "name": "clockman",
+            "status": "ready",
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "server_id": null,
+            "name": "wvonrueden",
+            "status": "ready",
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/databases +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

create

+ +

+requires authentication +

+ +

Create a new database.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/databases" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"name\": \"nesciunt\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/databases';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'name' => 'nesciunt',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/databases"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "name": "nesciunt"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "name": "johanna76",
+    "status": "ready",
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/databases +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+

Body Parameters

+
+ name   +string  +   + +
+

Example: nesciunt

+
+
+ +

show

+ +

+requires authentication +

+ +

Get a database by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/databases/6" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/databases/6';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/databases/6"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "name": "chloe.huel",
+    "status": "ready",
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/databases/{id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ id   +integer  +   + +
+

The ID of the database. Example: 6

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete database.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3/databases/6" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/databases/6';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/databases/6"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id}/databases/{database_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ database_id   +integer  +   + +
+

The ID of the database. Example: 6

+
+
+ +

firewall-rules

+ + + +

list

+ +

+requires authentication +

+ +

Get all firewall rules.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/firewall-rules" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/firewall-rules';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/firewall-rules"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "server_id": null,
+            "type": "allow",
+            "protocol": "tcp",
+            "port": 18074,
+            "source": "189.27.156.82",
+            "mask": 24,
+            "note": "test",
+            "status": null,
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "server_id": null,
+            "type": "allow",
+            "protocol": "tcp",
+            "port": 41088,
+            "source": "86.177.121.87",
+            "mask": 24,
+            "note": "test",
+            "status": null,
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/firewall-rules +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

create

+ +

+requires authentication +

+ +

Create a new firewall rule.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/firewall-rules" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"type\": \"allow\",
+    \"protocol\": \"udp\",
+    \"port\": \"voluptates\",
+    \"source\": \"saepe\",
+    \"mask\": \"0\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/firewall-rules';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'type' => 'allow',
+            'protocol' => 'udp',
+            'port' => 'voluptates',
+            'source' => 'saepe',
+            'mask' => '0',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/firewall-rules"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "type": "allow",
+    "protocol": "udp",
+    "port": "voluptates",
+    "source": "saepe",
+    "mask": "0"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "type": "allow",
+    "protocol": "tcp",
+    "port": 61992,
+    "source": "47.222.76.48",
+    "mask": 24,
+    "note": "test",
+    "status": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/firewall-rules +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+

Body Parameters

+
+ type   +string  +   + +
+

Example: allow

+Must be one of: +
  • allow
  • deny
+
+
+ protocol   +string  +   + +
+

Example: udp

+Must be one of: +
  • tcp
  • udp
+
+
+ port   +string  +   + +
+

Example: voluptates

+
+
+ source   +string  +   + +
+

Example: saepe

+
+
+ mask   +string  +   + +
+

Mask for source IP. Example: 0

+
+
+ +

show

+ +

+requires authentication +

+ +

Get a firewall rule by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/firewall-rules/7" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/firewall-rules/7';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/firewall-rules/7"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "type": "allow",
+    "protocol": "tcp",
+    "port": 43107,
+    "source": "135.73.216.16",
+    "mask": 24,
+    "note": "test",
+    "status": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/firewall-rules/{firewallRule_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ firewallRule_id   +integer  +   + +
+

The ID of the firewallRule. Example: 7

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete firewall rule.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3/firewall-rules/7" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/firewall-rules/7';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/firewall-rules/7"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id}/firewall-rules/{firewallRule_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ firewallRule_id   +integer  +   + +
+

The ID of the firewallRule. Example: 7

+
+
+ +

general

+ + + +

health-check

+ +

+

+ + + + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/health" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/health';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/health"
+);
+
+const headers = {
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+ + Show headers + +
cache-control: no-cache, private
+content-type: application/json
+x-ratelimit-limit: 60
+x-ratelimit-remaining: 59
+access-control-allow-origin: *
+ 
+
+{
+    "success": true,
+    "version": "2.0.0"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/health +

+

Headers

+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+
+ +

projects

+ + + +

list

+ +

+requires authentication +

+ +

Get all projects.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": 29,
+            "name": "Zachary Lueilwitz",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        },
+        {
+            "id": 30,
+            "name": "Mrs. Kiarra Heller IV",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+
+ +

create

+ +

+requires authentication +

+ +

Create a new project.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"name\": \"quos\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'name' => 'quos',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "name": "quos"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 29,
+    "name": "Hershel Spinka",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

Body Parameters

+
+ name   +string  +   + +
+

The name of the project. Example: quos

+
+
+ +

show

+ +

+requires authentication +

+ +

Get a project by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 29,
+    "name": "Emery Kiehn",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ +

update

+ +

+requires authentication +

+ +

Update project.

+ + +
Example request:
+ + +
+
curl --request PUT \
+    "https://your-vito-url/api/projects/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"name\": \"ut\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1';
+$response = $client->put(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'name' => 'ut',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "name": "ut"
+};
+
+fetch(url, {
+    method: "PUT",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 29,
+    "name": "Mable Prohaska",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ PUT + api/projects/{id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ id   +integer  +   + +
+

The ID of the project. Example: 1

+
+

Body Parameters

+
+ name   +string  +   + +
+

The name of the project. Example: ut

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete project.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ +

server-providers

+ + + +

list

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/server-providers" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/server-providers';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/server-providers"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": 2,
+            "project_id": null,
+            "global": true,
+            "name": "dolor",
+            "provider": "digitalocean",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        },
+        {
+            "id": 3,
+            "project_id": null,
+            "global": true,
+            "name": "enim",
+            "provider": "digitalocean",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/server-providers +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ +

create

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/server-providers" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"provider\": \"autem\",
+    \"name\": \"enim\",
+    \"token\": \"culpa\",
+    \"key\": \"sit\",
+    \"secret\": \"voluptates\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/server-providers';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'provider' => 'autem',
+            'name' => 'enim',
+            'token' => 'culpa',
+            'key' => 'sit',
+            'secret' => 'voluptates',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/server-providers"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "provider": "autem",
+    "name": "enim",
+    "token": "culpa",
+    "key": "sit",
+    "secret": "voluptates"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 2,
+    "project_id": null,
+    "global": true,
+    "name": "eligendi",
+    "provider": "aws",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/server-providers +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+

Body Parameters

+
+ provider   +string  +   + +
+

The provider (aws, linode, hetzner, digitalocean, vultr, ...) Example: autem

+
+
+ name   +string  +   + +
+

The name of the server provider. Example: enim

+
+
+ token   +string  +   + +
+

The token if provider requires api token Example: culpa

+
+
+ key   +string  +   + +
+

The key if provider requires key Example: sit

+
+
+ secret   +string  +   + +
+

The secret if provider requires key Example: voluptates

+
+
+ +

show

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/server-providers/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/server-providers/1';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/server-providers/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 2,
+    "project_id": null,
+    "global": true,
+    "name": "architecto",
+    "provider": "digitalocean",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/server-providers/{serverProvider_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ serverProvider_id   +integer  +   + +
+

The ID of the serverProvider. Example: 1

+
+
+ +

update

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request PUT \
+    "https://your-vito-url/api/projects/1/server-providers/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"name\": \"minus\",
+    \"global\": false
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/server-providers/1';
+$response = $client->put(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'name' => 'minus',
+            'global' => false,
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/server-providers/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "name": "minus",
+    "global": false
+};
+
+fetch(url, {
+    method: "PUT",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 2,
+    "project_id": null,
+    "global": true,
+    "name": "reiciendis",
+    "provider": "hetzner",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ PUT + api/projects/{project_id}/server-providers/{serverProvider_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ serverProvider_id   +integer  +   + +
+

The ID of the serverProvider. Example: 1

+
+

Body Parameters

+
+ name   +string  +   + +
+

The name of the server provider. Example: minus

+
+
+ global   +string  +   + +
+

Accessible in all projects Example: false

+Must be one of: +
  • 1
+
+
+ +

delete

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/server-providers/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/server-providers/1';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/server-providers/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/server-providers/{serverProvider_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ serverProvider_id   +integer  +   + +
+

The ID of the serverProvider. Example: 1

+
+
+ +

servers

+ + + +

list

+ +

+requires authentication +

+ +

Get all servers in a project.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "project_id": null,
+            "user_id": null,
+            "provider_id": null,
+            "name": "Dorthy Toy",
+            "ssh_user": "vito",
+            "ip": "172.132.95.155",
+            "local_ip": "118.57.197.65",
+            "port": 22,
+            "os": "ubuntu_22",
+            "type": "regular",
+            "type_data": null,
+            "provider": "custom",
+            "provider_data": null,
+            "public_key": "test",
+            "status": "ready",
+            "auto_update": null,
+            "available_updates": 0,
+            "security_updates": null,
+            "progress": 100,
+            "progress_step": null,
+            "updates": null,
+            "last_update_check": null,
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "project_id": null,
+            "user_id": null,
+            "provider_id": null,
+            "name": "Carrie Sporer",
+            "ssh_user": "vito",
+            "ip": "184.242.162.173",
+            "local_ip": "135.244.50.22",
+            "port": 22,
+            "os": "ubuntu_22",
+            "type": "regular",
+            "type_data": null,
+            "provider": "custom",
+            "provider_data": null,
+            "public_key": "test",
+            "status": "ready",
+            "auto_update": null,
+            "available_updates": 0,
+            "security_updates": null,
+            "progress": 100,
+            "progress_step": null,
+            "updates": null,
+            "last_update_check": null,
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ +

create

+ +

+requires authentication +

+ +

Create a new server.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"provider\": \"et\",
+    \"server_provider\": \"digitalocean\",
+    \"region\": \"inventore\",
+    \"plan\": \"atque\",
+    \"ip\": \"quam\",
+    \"port\": \"nemo\",
+    \"name\": \"perspiciatis\",
+    \"os\": \"similique\",
+    \"type\": \"regular\",
+    \"webserver\": \"none\",
+    \"database\": \"none\",
+    \"php\": \"8.1\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'provider' => 'et',
+            'server_provider' => 'digitalocean',
+            'region' => 'inventore',
+            'plan' => 'atque',
+            'ip' => 'quam',
+            'port' => 'nemo',
+            'name' => 'perspiciatis',
+            'os' => 'similique',
+            'type' => 'regular',
+            'webserver' => 'none',
+            'database' => 'none',
+            'php' => '8.1',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "provider": "et",
+    "server_provider": "digitalocean",
+    "region": "inventore",
+    "plan": "atque",
+    "ip": "quam",
+    "port": "nemo",
+    "name": "perspiciatis",
+    "os": "similique",
+    "type": "regular",
+    "webserver": "none",
+    "database": "none",
+    "php": "8.1"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "project_id": null,
+    "user_id": null,
+    "provider_id": null,
+    "name": "Flo Beer PhD",
+    "ssh_user": "vito",
+    "ip": "168.238.14.230",
+    "local_ip": "40.232.73.41",
+    "port": 22,
+    "os": "ubuntu_22",
+    "type": "regular",
+    "type_data": null,
+    "provider": "custom",
+    "provider_data": null,
+    "public_key": "test",
+    "status": "ready",
+    "auto_update": null,
+    "available_updates": 0,
+    "security_updates": null,
+    "progress": 100,
+    "progress_step": null,
+    "updates": null,
+    "last_update_check": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+

Body Parameters

+
+ provider   +string  +   + +
+

The server provider type Example: et

+
+
+ server_provider   +string  +   + +
+

If the provider is not custom, the ID of the server provider profile Example: digitalocean

+Must be one of: +
  • custom
  • hetzner
  • digitalocean
  • linode
  • vultr
+
+
+ region   +string  +   + +
+

Provider region if the provider is not custom Example: inventore

+
+
+ plan   +string  +   + +
+

Provider plan if the provider is not custom Example: atque

+
+
+ ip   +string  +   + +
+

SSH IP address if the provider is custom Example: quam

+
+
+ port   +string  +   + +
+

SSH Port if the provider is custom Example: nemo

+
+
+ name   +string  +   + +
+

The name of the server. Example: perspiciatis

+
+
+ os   +string  +   + +
+

The os of the server Example: similique

+
+
+ type   +string  +   + +
+

Server type Example: regular

+Must be one of: +
  • regular
  • database
+
+
+ webserver   +string  +   + +
+

Web server Example: none

+Must be one of: +
  • none
  • nginx
+
+
+ database   +string  +   + +
+

Database Example: none

+Must be one of: +
  • none
  • mysql57
  • mysql80
  • mariadb103
  • mariadb104
  • mariadb103
  • postgresql12
  • postgresql13
  • postgresql14
  • postgresql15
  • postgresql16
+
+
+ php   +string  +   + +
+

PHP version Example: 8.1

+Must be one of: +
  • 7.0
  • 7.1
  • 7.2
  • 7.3
  • 7.4
  • 8.0
  • 8.1
  • 8.2
  • 8.3
+
+
+ +

show

+ +

+requires authentication +

+ +

Get a server by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "project_id": null,
+    "user_id": null,
+    "provider_id": null,
+    "name": "Stephany Ankunding",
+    "ssh_user": "vito",
+    "ip": "145.28.94.46",
+    "local_ip": "69.133.44.100",
+    "port": 22,
+    "os": "ubuntu_22",
+    "type": "regular",
+    "type_data": null,
+    "provider": "custom",
+    "provider_data": null,
+    "public_key": "test",
+    "status": "ready",
+    "auto_update": null,
+    "available_updates": 0,
+    "security_updates": null,
+    "progress": 100,
+    "progress_step": null,
+    "updates": null,
+    "last_update_check": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

reboot

+ +

+requires authentication +

+ +

Reboot a server.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/reboot" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/reboot';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/reboot"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/reboot +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

upgrade

+ +

+requires authentication +

+ +

Upgrade server.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/upgrade" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/upgrade';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/upgrade"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/upgrade +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete server.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

services

+ + + +

list

+ +

+requires authentication +

+ +

Get all services.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/services" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "server_id": null,
+            "type": null,
+            "type_data": null,
+            "name": null,
+            "version": null,
+            "unit": null,
+            "status": null,
+            "is_default": null,
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "server_id": null,
+            "type": null,
+            "type_data": null,
+            "name": null,
+            "version": null,
+            "unit": null,
+            "status": null,
+            "is_default": null,
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/services +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

show

+ +

+requires authentication +

+ +

Get a service by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/services/27" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services/27';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services/27"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "type": null,
+    "type_data": null,
+    "name": null,
+    "version": null,
+    "unit": null,
+    "status": null,
+    "is_default": null,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/services/{id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ id   +integer  +   + +
+

The ID of the service. Example: 27

+
+
+ +

start

+ +

+requires authentication +

+ +

Start service.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/services/27/start" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services/27/start';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services/27/start"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/services/{service_id}/start +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ service_id   +integer  +   + +
+

The ID of the service. Example: 27

+
+
+ +

stop

+ +

+requires authentication +

+ +

Stop service.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/services/27/stop" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services/27/stop';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services/27/stop"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/services/{service_id}/stop +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ service_id   +integer  +   + +
+

The ID of the service. Example: 27

+
+
+ +

restart

+ +

+requires authentication +

+ +

Restart service.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/services/27/restart" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services/27/restart';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services/27/restart"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/services/{service_id}/restart +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ service_id   +integer  +   + +
+

The ID of the service. Example: 27

+
+
+ +

enable

+ +

+requires authentication +

+ +

Enable service.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/services/27/enable" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services/27/enable';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services/27/enable"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/services/{service_id}/enable +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ service_id   +integer  +   + +
+

The ID of the service. Example: 27

+
+
+ +

disable

+ +

+requires authentication +

+ +

Disable service.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/services/27/disable" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services/27/disable';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services/27/disable"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/services/{service_id}/disable +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ service_id   +integer  +   + +
+

The ID of the service. Example: 27

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete service.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3/services/27" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/services/27';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/services/27"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id}/services/{service_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ service_id   +integer  +   + +
+

The ID of the service. Example: 27

+
+
+ +

sites

+ + + +

list

+ +

+requires authentication +

+ +

Get all sites.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/sites" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/sites';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/sites"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "server_id": null,
+            "source_control_id": null,
+            "type": "laravel",
+            "type_data": null,
+            "domain": "test.com",
+            "aliases": null,
+            "web_directory": "/",
+            "path": "/home",
+            "php_version": "8.2",
+            "repository": null,
+            "branch": "main",
+            "status": "ready",
+            "port": null,
+            "progress": 100,
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "server_id": null,
+            "source_control_id": null,
+            "type": "laravel",
+            "type_data": null,
+            "domain": "test.com",
+            "aliases": null,
+            "web_directory": "/",
+            "path": "/home",
+            "php_version": "8.2",
+            "repository": null,
+            "branch": "main",
+            "status": "ready",
+            "port": null,
+            "progress": 100,
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/sites +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

create

+ +

+requires authentication +

+ +

Create a new site.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/sites" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"type\": \"wordpress\",
+    \"domain\": \"quo\",
+    \"aliases\": [
+        \"dolorum\"
+    ],
+    \"php_version\": \"7.4\",
+    \"web_directory\": \"public\",
+    \"source_control\": \"explicabo\",
+    \"repository\": \"organization\\/repository\",
+    \"branch\": \"main\",
+    \"composer\": true,
+    \"version\": \"5.2.1\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/sites';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'type' => 'wordpress',
+            'domain' => 'quo',
+            'aliases' => [
+                'dolorum',
+            ],
+            'php_version' => '7.4',
+            'web_directory' => 'public',
+            'source_control' => 'explicabo',
+            'repository' => 'organization/repository',
+            'branch' => 'main',
+            'composer' => true,
+            'version' => '5.2.1',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/sites"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "type": "wordpress",
+    "domain": "quo",
+    "aliases": [
+        "dolorum"
+    ],
+    "php_version": "7.4",
+    "web_directory": "public",
+    "source_control": "explicabo",
+    "repository": "organization\/repository",
+    "branch": "main",
+    "composer": true,
+    "version": "5.2.1"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "source_control_id": null,
+    "type": "laravel",
+    "type_data": null,
+    "domain": "test.com",
+    "aliases": null,
+    "web_directory": "/",
+    "path": "/home",
+    "php_version": "8.2",
+    "repository": null,
+    "branch": "main",
+    "status": "ready",
+    "port": null,
+    "progress": 100,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/sites +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+

Body Parameters

+
+ type   +string  +   + +
+

Example: wordpress

+Must be one of: +
  • php
  • php-blank
  • phpmyadmin
  • laravel
  • wordpress
+
+
+ domain   +string  +   + +
+

Example: quo

+
+
+ aliases   +string[]  +   + + +
+ +
+
+ php_version   +string  +   + +
+

One of the installed PHP Versions Example: 7.4

+
+
+ web_directory   +string  +   + +
+

Required for PHP and Laravel sites Example: public

+
+
+ source_control   +string  +   + +
+

Source control ID, Required for Sites which support source control Example: explicabo

+
+
+ repository   +string  +   + +
+

Repository, Required for Sites which support source control Example: organization/repository

+
+
+ branch   +string  +   + +
+

Branch, Required for Sites which support source control Example: main

+
+
+ composer   +boolean  +   + + +
+

Run composer if site supports composer Example: true

+
+
+ version   +string  +   + +
+

Version, if the site type requires a version like PHPMyAdmin Example: 5.2.1

+
+
+ +

show

+ +

+requires authentication +

+ +

Get a site by ID.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/sites/8" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/sites/8';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/sites/8"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "server_id": null,
+    "source_control_id": null,
+    "type": "laravel",
+    "type_data": null,
+    "domain": "test.com",
+    "aliases": null,
+    "web_directory": "/",
+    "path": "/home",
+    "php_version": "8.2",
+    "repository": null,
+    "branch": "main",
+    "status": "ready",
+    "port": null,
+    "progress": 100,
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/sites/{id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ id   +integer  +   + +
+

The ID of the site. Example: 8

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete site.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3/sites/8" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/sites/8';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/sites/8"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id}/sites/{site_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ site_id   +integer  +   + +
+

The ID of the site. Example: 8

+
+
+ +

source-controls

+ + + +

list

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/source-controls" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/source-controls';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/source-controls"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": 5,
+            "project_id": null,
+            "global": true,
+            "name": "Jaiden Kling",
+            "provider": "github",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        },
+        {
+            "id": 6,
+            "project_id": null,
+            "global": true,
+            "name": "Ms. Brianne Bosco",
+            "provider": "github",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/source-controls +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ +

create

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/source-controls" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"provider\": \"bitbucket\",
+    \"name\": \"eos\",
+    \"token\": \"et\",
+    \"url\": \"https:\\/\\/lueilwitz.com\\/nostrum-et-porro-atque-sint.html\",
+    \"username\": \"consectetur\",
+    \"password\": \"PL.P?{06\\\\ECi0\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/source-controls';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'provider' => 'bitbucket',
+            'name' => 'eos',
+            'token' => 'et',
+            'url' => 'https://lueilwitz.com/nostrum-et-porro-atque-sint.html',
+            'username' => 'consectetur',
+            'password' => 'PL.P?{06\\ECi0',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/source-controls"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "provider": "bitbucket",
+    "name": "eos",
+    "token": "et",
+    "url": "https:\/\/lueilwitz.com\/nostrum-et-porro-atque-sint.html",
+    "username": "consectetur",
+    "password": "PL.P?{06\\ECi0"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 5,
+    "project_id": null,
+    "global": true,
+    "name": "Toby Parker",
+    "provider": "github",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/source-controls +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+

Body Parameters

+
+ provider   +string  +   + +
+

The provider Example: bitbucket

+Must be one of: +
  • gitlab
  • github
  • bitbucket
+
+
+ name   +string  +   + +
+

The name of the storage provider. Example: eos

+
+
+ token   +string  +   + +
+

The token if provider requires api token Example: et

+
+
+ url   +string  +   + +
+

The URL if the provider is Gitlab and it is self-hosted Example: https://lueilwitz.com/nostrum-et-porro-atque-sint.html

+
+
+ username   +string  +   + +
+

The username if the provider is Bitbucket Example: consectetur

+
+
+ password   +string  +   + +
+

The password if the provider is Bitbucket Example: PL.P?{06\ECi0

+
+
+ +

show

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/source-controls/3" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/source-controls/3';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/source-controls/3"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 5,
+    "project_id": null,
+    "global": true,
+    "name": "Prof. Bartholome Graham IV",
+    "provider": "github",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/source-controls/{sourceControl_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ sourceControl_id   +integer  +   + +
+

The ID of the sourceControl. Example: 3

+
+
+ +

update

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request PUT \
+    "https://your-vito-url/api/projects/1/source-controls/3" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"name\": \"quaerat\",
+    \"token\": \"consectetur\",
+    \"url\": \"http:\\/\\/www.hudson.biz\\/rerum-voluptatem-debitis-accusamus\",
+    \"username\": \"voluptatem\",
+    \"password\": \"\\\\p\\/el>)3#~E?kI\",
+    \"global\": false
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/source-controls/3';
+$response = $client->put(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'name' => 'quaerat',
+            'token' => 'consectetur',
+            'url' => 'http://www.hudson.biz/rerum-voluptatem-debitis-accusamus',
+            'username' => 'voluptatem',
+            'password' => '\\p/el>)3#~E?kI',
+            'global' => false,
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/source-controls/3"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "name": "quaerat",
+    "token": "consectetur",
+    "url": "http:\/\/www.hudson.biz\/rerum-voluptatem-debitis-accusamus",
+    "username": "voluptatem",
+    "password": "\\p\/el>)3#~E?kI",
+    "global": false
+};
+
+fetch(url, {
+    method: "PUT",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 5,
+    "project_id": null,
+    "global": true,
+    "name": "Cicero Smitham",
+    "provider": "github",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ PUT + api/projects/{project_id}/source-controls/{sourceControl_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ sourceControl_id   +integer  +   + +
+

The ID of the sourceControl. Example: 3

+
+

Body Parameters

+
+ name   +string  +   + +
+

The name of the storage provider. Example: quaerat

+
+
+ token   +string  +   + +
+

The token if provider requires api token Example: consectetur

+
+
+ url   +string  +   + +
+

The URL if the provider is Gitlab and it is self-hosted Example: http://www.hudson.biz/rerum-voluptatem-debitis-accusamus

+
+
+ username   +string  +   + +
+

The username if the provider is Bitbucket Example: voluptatem

+
+
+ password   +string  +   + +
+

The password if the provider is Bitbucket Example: \p/el>)3#~E?kI

+
+
+ global   +string  +   + +
+

Accessible in all projects Example: false

+Must be one of: +
  • 1
+
+
+ +

delete

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/source-controls/3" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/source-controls/3';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/source-controls/3"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/source-controls/{sourceControl_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ sourceControl_id   +integer  +   + +
+

The ID of the sourceControl. Example: 3

+
+
+ +

ssh-keys

+ + + +

list

+ +

+requires authentication +

+ +

Get all ssh keys.

+ + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/servers/3/ssh-keys" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/ssh-keys';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/ssh-keys"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": null,
+            "user": null,
+            "name": "Dr. Reanna Braun",
+            "created_at": null,
+            "updated_at": null
+        },
+        {
+            "id": null,
+            "user": null,
+            "name": "Norene Fritsch",
+            "created_at": null,
+            "updated_at": null
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/servers/{server_id}/ssh-keys +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ +

create

+ +

+requires authentication +

+ +

Deploy ssh key to server.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/servers/3/ssh-keys" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"key_id\": \"vero\",
+    \"name\": \"voluptates\",
+    \"public_key\": \"dolor\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/ssh-keys';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'key_id' => 'vero',
+            'name' => 'voluptates',
+            'public_key' => 'dolor',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/ssh-keys"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "key_id": "vero",
+    "name": "voluptates",
+    "public_key": "dolor"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": null,
+    "user": null,
+    "name": "Sophia D'Amore",
+    "created_at": null,
+    "updated_at": null
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/servers/{server_id}/ssh-keys +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+

Body Parameters

+
+ key_id   +string  +   + +
+

The ID of the key. Example: vero

+
+
+ name   +string  +   + +
+

Key name, required if key_id is not provided. Example: voluptates

+
+
+ public_key   +string  +   + +
+

Public Key, required if key_id is not provided. Example: dolor

+
+
+ +

delete

+ +

+requires authentication +

+ +

Delete ssh key from server.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/servers/3/ssh-keys/4" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/servers/3/ssh-keys/4';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/servers/3/ssh-keys/4"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/servers/{server_id}/ssh-keys/{sshKey_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ server_id   +integer  +   + +
+

The ID of the server. Example: 3

+
+
+ sshKey_id   +integer  +   + +
+

The ID of the sshKey. Example: 4

+
+
+ +

storage-providers

+ + + +

list

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/storage-providers" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/storage-providers';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/storage-providers"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "data": [
+        {
+            "id": 3,
+            "project_id": null,
+            "global": true,
+            "name": "et",
+            "provider": "local",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        },
+        {
+            "id": 4,
+            "project_id": null,
+            "global": true,
+            "name": "sed",
+            "provider": "local",
+            "created_at": "2024-11-01T15:40:48.000000Z",
+            "updated_at": "2024-11-01T15:40:48.000000Z"
+        }
+    ],
+    "links": {
+        "first": "/?page=1",
+        "last": "/?page=1",
+        "prev": null,
+        "next": null
+    },
+    "meta": {
+        "current_page": 1,
+        "from": 1,
+        "last_page": 1,
+        "links": [
+            {
+                "url": null,
+                "label": "&laquo; Previous",
+                "active": false
+            },
+            {
+                "url": "/?page=1",
+                "label": "1",
+                "active": true
+            },
+            {
+                "url": null,
+                "label": "Next &raquo;",
+                "active": false
+            }
+        ],
+        "path": "/",
+        "per_page": 25,
+        "to": 2,
+        "total": 2
+    }
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/storage-providers +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ +

create

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request POST \
+    "https://your-vito-url/api/projects/1/storage-providers" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"provider\": \"quod\",
+    \"name\": \"commodi\",
+    \"token\": \"ipsum\",
+    \"key\": \"ratione\",
+    \"secret\": \"iste\"
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/storage-providers';
+$response = $client->post(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'provider' => 'quod',
+            'name' => 'commodi',
+            'token' => 'ipsum',
+            'key' => 'ratione',
+            'secret' => 'iste',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/storage-providers"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "provider": "quod",
+    "name": "commodi",
+    "token": "ipsum",
+    "key": "ratione",
+    "secret": "iste"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 3,
+    "project_id": null,
+    "global": true,
+    "name": "est",
+    "provider": "dropbox",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ POST + api/projects/{project_id}/storage-providers +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+

Body Parameters

+
+ provider   +string  +   + +
+

The provider (aws, linode, hetzner, digitalocean, vultr, ...) Example: quod

+
+
+ name   +string  +   + +
+

The name of the storage provider. Example: commodi

+
+
+ token   +string  +   + +
+

The token if provider requires api token Example: ipsum

+
+
+ key   +string  +   + +
+

The key if provider requires key Example: ratione

+
+
+ secret   +string  +   + +
+

The secret if provider requires key Example: iste

+
+
+ +

show

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request GET \
+    --get "https://your-vito-url/api/projects/1/storage-providers/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/storage-providers/1';
+$response = $client->get(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/storage-providers/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "GET",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 3,
+    "project_id": null,
+    "global": true,
+    "name": "officia",
+    "provider": "ftp",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ GET + api/projects/{project_id}/storage-providers/{storageProvider_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ storageProvider_id   +integer  +   + +
+

The ID of the storageProvider. Example: 1

+
+
+ +

update

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request PUT \
+    "https://your-vito-url/api/projects/1/storage-providers/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"name\": \"iusto\",
+    \"global\": true
+}"
+
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/storage-providers/1';
+$response = $client->put(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+        'json' => [
+            'name' => 'iusto',
+            'global' => true,
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/storage-providers/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "name": "iusto",
+    "global": true
+};
+
+fetch(url, {
+    method: "PUT",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + +
+

Example response (200):

+
+
+
+{
+    "id": 3,
+    "project_id": null,
+    "global": true,
+    "name": "rerum",
+    "provider": "ftp",
+    "created_at": "2024-11-01T15:40:48.000000Z",
+    "updated_at": "2024-11-01T15:40:48.000000Z"
+}
+ 
+
+ + +
+

+ Request    + +    + +

+

+ PUT + api/projects/{project_id}/storage-providers/{storageProvider_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ storageProvider_id   +integer  +   + +
+

The ID of the storageProvider. Example: 1

+
+

Body Parameters

+
+ name   +string  +   + +
+

The name of the storage provider. Example: iusto

+
+
+ global   +string  +   + +
+

Accessible in all projects Example: true

+Must be one of: +
  • 1
+
+
+ +

delete

+ +

+requires authentication +

+ + + + +
Example request:
+ + +
+
curl --request DELETE \
+    "https://your-vito-url/api/projects/1/storage-providers/1" \
+    --header "Authorization: Bearer YOUR-API-KEY" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
$client = new \GuzzleHttp\Client();
+$url = 'https://your-vito-url/api/projects/1/storage-providers/1';
+$response = $client->delete(
+    $url,
+    [
+        'headers' => [
+            'Authorization' => 'Bearer YOUR-API-KEY',
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ],
+    ]
+);
+$body = $response->getBody();
+print_r(json_decode((string) $body));
+ + +
+
const url = new URL(
+    "https://your-vito-url/api/projects/1/storage-providers/1"
+);
+
+const headers = {
+    "Authorization": "Bearer YOUR-API-KEY",
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + +
+

Example response (204):

+
+
+Empty response
+ 
+
+ + +
+

+ Request    + +    + +

+

+ DELETE + api/projects/{project_id}/storage-providers/{storageProvider_id} +

+

Headers

+
+ Authorization   +  +   + +
+

Example: Bearer YOUR-API-KEY

+
+
+ Content-Type   +  +   + +
+

Example: application/json

+
+
+ Accept   +  +   + +
+

Example: application/json

+
+

URL Parameters

+
+ project_id   +integer  +   + +
+

The ID of the project. Example: 1

+
+
+ storageProvider_id   +integer  +   + +
+

The ID of the storageProvider. Example: 1

+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/public/api-docs/js/theme-default-4.38.0.js b/public/api-docs/js/theme-default-4.38.0.js new file mode 100644 index 0000000..31c8451 --- /dev/null +++ b/public/api-docs/js/theme-default-4.38.0.js @@ -0,0 +1,149 @@ +document.addEventListener('DOMContentLoaded', function() { + const updateHash = function (id) { + window.location.hash = `#${id}`; + }; + + const navButton = document.getElementById('nav-button'); + const menuWrapper = document.querySelector('.tocify-wrapper'); + function toggleSidebar(event) { + event.preventDefault(); + if (menuWrapper) { + menuWrapper.classList.toggle('open'); + navButton.classList.toggle('open'); + } + } + function closeSidebar() { + if (menuWrapper) { + menuWrapper.classList.remove('open'); + navButton.classList.remove('open'); + } + } + navButton.addEventListener('click', toggleSidebar); + + window.hljs.highlightAll(); + + const wrapper = document.getElementById('toc'); + // https://jets.js.org/ + window.jets = new window.Jets({ + // *OR - Selects elements whose values contains at least one part of search substring + searchSelector: '*OR', + searchTag: '#input-search', + contentTag: '#toc li', + didSearch: function(term) { + wrapper.classList.toggle('jets-searching', String(term).length > 0) + }, + // map these accent keys to plain values + diacriticsMap: { + a: 'ÀÁÂÃÄÅàáâãäåĀāąĄ', + c: 'ÇçćĆčČ', + d: 'đĐďĎ', + e: 'ÈÉÊËèéêëěĚĒēęĘ', + i: 'ÌÍÎÏìíîïĪī', + l: 'łŁ', + n: 'ÑñňŇńŃ', + o: 'ÒÓÔÕÕÖØòóôõöøŌō', + r: 'řŘ', + s: 'ŠšśŚ', + t: 'ťŤ', + u: 'ÙÚÛÜùúûüůŮŪū', + y: 'ŸÿýÝ', + z: 'ŽžżŻźŹ' + } + }); + + function hashChange() { + const currentItems = document.querySelectorAll('.tocify-subheader.visible, .tocify-item.tocify-focus'); + Array.from(currentItems).forEach((elem) => { + elem.classList.remove('visible', 'tocify-focus'); + }); + + const currentTag = document.querySelector(`a[href="${window.location.hash}"]`); + if (currentTag) { + const parent = currentTag.closest('.tocify-subheader'); + if (parent) { + parent.classList.add('visible'); + } + + const siblings = currentTag.closest('.tocify-header'); + if (siblings) { + Array.from(siblings.querySelectorAll('.tocify-subheader')).forEach((elem) => { + elem.classList.add('visible'); + }); + } + + currentTag.parentElement.classList.add('tocify-focus'); + + // wait for dom changes to be done + setTimeout(() => { + currentTag.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' }); + // only close the sidebar on level-2 events + if (currentTag.parentElement.classList.contains('level-2')) { + closeSidebar(); + } + }, 1500); + } + } + + let languages = JSON.parse(document.body.getAttribute('data-languages')); + // Support a key => value object where the key is the name, or an array of strings where the value is the name + if (!Array.isArray(languages)) { + languages = Object.values(languages); + } + // if there is no language use the first one + const currentLanguage = window.localStorage.getItem('language') || languages[0]; + const languageStyle = document.getElementById('language-style'); + const langSelector = document.querySelectorAll('.lang-selector button.lang-button'); + + function setActiveLanguage(newLanguage) { + window.localStorage.setItem('language', newLanguage); + if (!languageStyle) { + return; + } + + const newStyle = languages.map((language) => { + return language === newLanguage + // the current one should be visible + ? `body .content .${language}-example pre { display: block; }` + // the inactive one should be hidden + : `body .content .${language}-example pre { display: none; }`; + }).join(`\n`); + + Array.from(langSelector).forEach((elem) => { + elem.classList.toggle('active', elem.getAttribute('data-language-name') === newLanguage); + }); + + const activeHash = window.location.hash.slice(1); + + languageStyle.innerHTML = newStyle; + + setTimeout(() => { + updateHash(activeHash); + }, 200); + } + + setActiveLanguage(currentLanguage); + + Array.from(langSelector).forEach((elem) => { + elem.addEventListener('click', () => { + const newLanguage = elem.getAttribute('data-language-name'); + setActiveLanguage(newLanguage); + }); + }); + + window.addEventListener('hashchange', hashChange, false); + + const divs = document.querySelectorAll('.content h1[id], .content h2[id]'); + + document.addEventListener('scroll', () => { + divs.forEach(item => { + const rect = item.getBoundingClientRect(); + if (rect.top > 0 && rect.top < 150) { + const location = window.location.toString().split('#')[0]; + history.replaceState(null, null, location + '#' + item.id); + hashChange(); + } + }); + }); + + hashChange(); +}); diff --git a/public/api-docs/js/tryitout-4.38.0.js b/public/api-docs/js/tryitout-4.38.0.js new file mode 100644 index 0000000..2a1d2b8 --- /dev/null +++ b/public/api-docs/js/tryitout-4.38.0.js @@ -0,0 +1,289 @@ +window.abortControllers = {}; + +function cacheAuthValue() { + // Whenever the auth header is set for one endpoint, cache it for the others + window.lastAuthValue = ''; + let authInputs = document.querySelectorAll(`.auth-value`) + authInputs.forEach(el => { + el.addEventListener('input', (event) => { + window.lastAuthValue = event.target.value; + authInputs.forEach(otherInput => { + if (otherInput === el) return; + // Don't block the main thread + setTimeout(() => { + otherInput.value = window.lastAuthValue; + }, 0); + }); + }); + }); +} + +window.addEventListener('DOMContentLoaded', cacheAuthValue); + +function getCookie(name) { + if (!document.cookie) { + return null; + } + + const cookies = document.cookie.split(';') + .map(c => c.trim()) + .filter(c => c.startsWith(name + '=')); + + if (cookies.length === 0) { + return null; + } + + return decodeURIComponent(cookies[0].split('=')[1]); +} + +function tryItOut(endpointId) { + document.querySelector(`#btn-tryout-${endpointId}`).hidden = true; + document.querySelector(`#btn-canceltryout-${endpointId}`).hidden = false; + const executeBtn = document.querySelector(`#btn-executetryout-${endpointId}`).hidden = false; + executeBtn.disabled = false; + + // Show all input fields + document.querySelectorAll(`input[data-endpoint=${endpointId}],label[data-endpoint=${endpointId}]`) + .forEach(el => el.style.display = 'block'); + + if (document.querySelector(`#form-${endpointId}`).dataset.authed === "1") { + const authElement = document.querySelector(`#auth-${endpointId}`); + authElement && (authElement.hidden = false); + } + // Expand all nested fields + document.querySelectorAll(`#form-${endpointId} details`) + .forEach(el => el.open = true); +} + +function cancelTryOut(endpointId) { + if (window.abortControllers[endpointId]) { + window.abortControllers[endpointId].abort(); + delete window.abortControllers[endpointId]; + } + + document.querySelector(`#btn-tryout-${endpointId}`).hidden = false; + const executeBtn = document.querySelector(`#btn-executetryout-${endpointId}`); + executeBtn.hidden = true; + executeBtn.textContent = executeBtn.dataset.initialText; + document.querySelector(`#btn-canceltryout-${endpointId}`).hidden = true; + // Hide inputs + document.querySelectorAll(`input[data-endpoint=${endpointId}],label[data-endpoint=${endpointId}]`) + .forEach(el => el.style.display = 'none'); + document.querySelectorAll(`#form-${endpointId} details`) + .forEach(el => el.open = false); + const authElement = document.querySelector(`#auth-${endpointId}`); + authElement && (authElement.hidden = true); + + document.querySelector('#execution-results-' + endpointId).hidden = true; + document.querySelector('#execution-error-' + endpointId).hidden = true; + + // Revert to sample code blocks + document.querySelector('#example-requests-' + endpointId).hidden = false; + document.querySelector('#example-responses-' + endpointId).hidden = false; +} + +function makeAPICall(method, path, body = {}, query = {}, headers = {}, endpointId = null) { + console.log({endpointId, path, body, query, headers}); + + if (!(body instanceof FormData) && typeof body !== "string") { + body = JSON.stringify(body) + } + + const url = new URL(window.tryItOutBaseUrl + '/' + path.replace(/^\//, '')); + + // We need this function because if you try to set an array or object directly to a URLSearchParams object, + // you'll get [object Object] or the array.toString() + function addItemToSearchParamsObject(key, value, searchParams) { + if (Array.isArray(value)) { + value.forEach((v, i) => { + // Append {filters: [first, second]} as filters[0]=first&filters[1]second + addItemToSearchParamsObject(key + '[' + i + ']', v, searchParams); + }) + } else if (typeof value === 'object' && value !== null) { + Object.keys(value).forEach((i) => { + // Append {filters: {name: first}} as filters[name]=first + addItemToSearchParamsObject(key + '[' + i + ']', value[i], searchParams); + }); + } else { + searchParams.append(key, value); + } + } + + Object.keys(query) + .forEach(key => addItemToSearchParamsObject(key, query[key], url.searchParams)); + + window.abortControllers[endpointId] = new AbortController(); + + return fetch(url, { + method, + headers, + body: method === 'GET' ? undefined : body, + signal: window.abortControllers[endpointId].signal, + referrer: window.tryItOutBaseUrl, + mode: 'cors', + credentials: 'same-origin', + }) + .then(response => Promise.all([response.status, response.statusText, response.text(), response.headers])); +} + +function hideCodeSamples(endpointId) { + document.querySelector('#example-requests-' + endpointId).hidden = true; + document.querySelector('#example-responses-' + endpointId).hidden = true; +} + +function handleResponse(endpointId, response, status, headers) { + hideCodeSamples(endpointId); + + // Hide error views + document.querySelector('#execution-error-' + endpointId).hidden = true; + + const responseContentEl = document.querySelector('#execution-response-content-' + endpointId); + + // Check if the response contains Laravel's dd() default dump output + const isLaravelDump = response.includes('Sfdump'); + + // If it's a Laravel dd() dump, use innerHTML to render it safely + if (isLaravelDump) { + responseContentEl.innerHTML = response === '' ? responseContentEl.dataset.emptyResponseText : response; + } else { + // Otherwise, stick to textContent for regular responses + responseContentEl.textContent = response === '' ? responseContentEl.dataset.emptyResponseText : response; + } + + // Prettify it if it's JSON + let isJson = false; + try { + const jsonParsed = JSON.parse(response); + if (jsonParsed !== null) { + isJson = true; + response = JSON.stringify(jsonParsed, null, 4); + responseContentEl.textContent = response; + } + } catch (e) { + + } + + isJson && window.hljs.highlightElement(responseContentEl); + const statusEl = document.querySelector('#execution-response-status-' + endpointId); + statusEl.textContent = ` (${status})`; + document.querySelector('#execution-results-' + endpointId).hidden = false; + statusEl.scrollIntoView({behavior: "smooth", block: "center"}); +} + +function handleError(endpointId, err) { + hideCodeSamples(endpointId); + // Hide response views + document.querySelector('#execution-results-' + endpointId).hidden = true; + + // Show error views + let errorMessage = err.message || err; + const $errorMessageEl = document.querySelector('#execution-error-message-' + endpointId); + $errorMessageEl.textContent = errorMessage + $errorMessageEl.textContent; + const errorEl = document.querySelector('#execution-error-' + endpointId); + errorEl.hidden = false; + errorEl.scrollIntoView({behavior: "smooth", block: "center"}); + +} + +async function executeTryOut(endpointId, form) { + const executeBtn = document.querySelector(`#btn-executetryout-${endpointId}`); + executeBtn.textContent = executeBtn.dataset.loadingText; + executeBtn.disabled = true; + executeBtn.scrollIntoView({behavior: "smooth", block: "center"}); + + let body; + let setter; + if (form.dataset.hasfiles === "1") { + body = new FormData(); + setter = (name, value) => body.append(name, value); + } else if (form.dataset.isarraybody === "1") { + body = []; + setter = (name, value) => _.set(body, name, value); + } else { + body = {}; + setter = (name, value) => _.set(body, name, value); + } + const bodyParameters = form.querySelectorAll('input[data-component=body]'); + bodyParameters.forEach(el => { + let value = el.value; + + if (el.type === 'number' && typeof value === 'string') { + value = parseFloat(value); + } + + if (el.type === 'file' && el.files[0]) { + setter(el.name, el.files[0]); + return; + } + + if (el.type !== 'radio') { + if (value === "" && el.required === false) { + // Don't include empty optional values in the request + return; + } + setter(el.name, value); + return; + } + + if (el.checked) { + value = (value === 'false') ? false : true; + setter(el.name, value); + } + }); + + const query = {}; + const queryParameters = form.querySelectorAll('input[data-component=query]'); + queryParameters.forEach(el => { + if (el.type !== 'radio' || (el.type === 'radio' && el.checked)) { + if (el.value === '') { + // Don't include empty values in the request + return; + } + + _.set(query, el.name, el.value); + } + }); + + let path = form.dataset.path; + const urlParameters = form.querySelectorAll('input[data-component=url]'); + urlParameters.forEach(el => (path = path.replace(new RegExp(`\\{${el.name}\\??}`), el.value))); + + const headers = Object.fromEntries(Array.from(form.querySelectorAll('input[data-component=header]')) + .map(el => [el.name, el.value])); + + // When using FormData, the browser sets the correct content-type + boundary + let method = form.dataset.method; + if (body instanceof FormData) { + delete headers['Content-Type']; + + // When using FormData with PUT or PATCH, use method spoofing so PHP can access the post body + if (['PUT', 'PATCH'].includes(form.dataset.method)) { + method = 'POST'; + setter('_method', form.dataset.method); + } + } + + let preflightPromise = Promise.resolve(); + if (window.useCsrf && window.csrfUrl) { + preflightPromise = makeAPICall('GET', window.csrfUrl).then(() => { + headers['X-XSRF-TOKEN'] = getCookie('XSRF-TOKEN'); + }); + } + + return preflightPromise.then(() => makeAPICall(method, path, body, query, headers, endpointId)) + .then(([responseStatus, statusText, responseContent, responseHeaders]) => { + handleResponse(endpointId, responseContent, responseStatus, responseHeaders) + }) + .catch(err => { + if (err.name === "AbortError") { + console.log("Request cancelled"); + return; + } + console.log("Error while making request: ", err); + handleError(endpointId, err); + }) + .finally(() => { + executeBtn.disabled = false; + executeBtn.textContent = executeBtn.dataset.initialText; + }); +} diff --git a/public/api-docs/openapi.yaml b/public/api-docs/openapi.yaml new file mode 100644 index 0000000..18b53ad --- /dev/null +++ b/public/api-docs/openapi.yaml @@ -0,0 +1,5259 @@ +openapi: 3.0.3 +info: + title: 'API Documentation' + description: "VitoDeploy's API documentation." + version: 1.0.0 +servers: + - + url: 'https://your-vito-url' +paths: + '/api/projects/{project_id}/servers/{server_id}/cron-jobs': + get: + summary: list + operationId: list + description: 'Get all cron jobs.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + server_id: null + command: 'ls -la' + user: root + frequency: '* * * * *' + status: ready + created_at: null + updated_at: null + - + id: null + server_id: null + command: 'ls -la' + user: root + frequency: '* * * * *' + status: ready + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + server_id: null + command: 'ls -la' + user: root + frequency: '* * * * *' + status: ready + created_at: null + updated_at: null + - + id: null + server_id: null + command: 'ls -la' + user: root + frequency: '* * * * *' + status: ready + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + server_id: + type: string + example: null + command: + type: string + example: 'ls -la' + user: + type: string + example: root + frequency: + type: string + example: '* * * * *' + status: + type: string + example: ready + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - cron-jobs + post: + summary: create + operationId: create + description: 'Create a new cron job.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + command: 'ls -la' + user: root + frequency: '* * * * *' + status: ready + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + command: + type: string + example: 'ls -la' + user: + type: string + example: root + frequency: + type: string + example: '* * * * *' + status: + type: string + example: ready + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - cron-jobs + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + command: + type: string + description: '' + example: qui + nullable: false + user: + type: string + description: '' + example: root + nullable: false + enum: + - root + - vito + frequency: + type: string + description: 'Frequency of the cron job.' + example: '* * * * *' + nullable: false + required: + - command + - user + - frequency + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/cron-jobs/{cronJob_id}': + get: + summary: show + operationId: show + description: 'Get a cron job by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + command: 'ls -la' + user: root + frequency: '* * * * *' + status: ready + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + command: + type: string + example: 'ls -la' + user: + type: string + example: root + frequency: + type: string + example: '* * * * *' + status: + type: string + example: ready + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - cron-jobs + delete: + summary: delete + operationId: delete + description: 'Delete cron job.' + parameters: [] + responses: + 204: + description: '' + tags: + - cron-jobs + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: cronJob_id + description: 'The ID of the cronJob.' + example: 5 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/database-users': + get: + summary: list + operationId: list + description: 'Get all database users.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + server_id: null + username: nyasia68 + databases: [] + host: '%' + status: null + created_at: null + updated_at: null + - + id: null + server_id: null + username: madyson20 + databases: [] + host: '%' + status: null + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + server_id: null + username: nyasia68 + databases: [] + host: '%' + status: null + created_at: null + updated_at: null + - + id: null + server_id: null + username: madyson20 + databases: [] + host: '%' + status: null + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + server_id: + type: string + example: null + username: + type: string + example: nyasia68 + databases: + type: array + example: [] + host: + type: string + example: '%' + status: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - database-users + post: + summary: create + operationId: create + description: 'Create a new database user.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + username: amya.nitzsche + databases: [] + host: '%' + status: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + username: + type: string + example: amya.nitzsche + databases: + type: array + example: [] + host: + type: string + example: '%' + status: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - database-users + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + username: + type: string + description: '' + example: dignissimos + nullable: false + password: + type: string + description: '' + example: OK+XEG2) + nullable: false + host: + type: string + description: 'Host, if it is a remote user.' + example: '%' + nullable: false + required: + - username + - password + - host + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}': + get: + summary: show + operationId: show + description: 'Get a database user by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + username: bergstrom.ericka + databases: [] + host: '%' + status: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + username: + type: string + example: bergstrom.ericka + databases: + type: array + example: [] + host: + type: string + example: '%' + status: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - database-users + delete: + summary: delete + operationId: delete + description: 'Delete database user.' + parameters: [] + responses: + 204: + description: '' + tags: + - database-users + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: databaseUser_id + description: 'The ID of the databaseUser.' + example: 4 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/database-users/{databaseUser_id}/link': + post: + summary: link + operationId: link + description: 'Link to databases' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + username: fmurray + databases: [] + host: '%' + status: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + username: + type: string + example: fmurray + databases: + type: array + example: [] + host: + type: string + example: '%' + status: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - database-users + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + databases: + type: string + description: 'Array of database names to link to the user.' + example: accusantium + nullable: false + required: + - databases + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: databaseUser_id + description: 'The ID of the databaseUser.' + example: 4 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/databases': + get: + summary: list + operationId: list + description: 'Get all databases.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + server_id: null + name: clockman + status: ready + created_at: null + updated_at: null + - + id: null + server_id: null + name: wvonrueden + status: ready + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + server_id: null + name: clockman + status: ready + created_at: null + updated_at: null + - + id: null + server_id: null + name: wvonrueden + status: ready + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + server_id: + type: string + example: null + name: + type: string + example: clockman + status: + type: string + example: ready + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - databases + post: + summary: create + operationId: create + description: 'Create a new database.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + name: johanna76 + status: ready + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + name: + type: string + example: johanna76 + status: + type: string + example: ready + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - databases + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: '' + example: nesciunt + nullable: false + required: + - name + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/databases/{id}': + get: + summary: show + operationId: show + description: 'Get a database by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + name: chloe.huel + status: ready + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + name: + type: string + example: chloe.huel + status: + type: string + example: ready + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - databases + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: id + description: 'The ID of the database.' + example: 6 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/databases/{database_id}': + delete: + summary: delete + operationId: delete + description: 'Delete database.' + parameters: [] + responses: + 204: + description: '' + tags: + - databases + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: database_id + description: 'The ID of the database.' + example: 6 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/firewall-rules': + get: + summary: list + operationId: list + description: 'Get all firewall rules.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + server_id: null + type: allow + protocol: tcp + port: 18074 + source: 189.27.156.82 + mask: 24 + note: test + status: null + created_at: null + updated_at: null + - + id: null + server_id: null + type: allow + protocol: tcp + port: 41088 + source: 86.177.121.87 + mask: 24 + note: test + status: null + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + server_id: null + type: allow + protocol: tcp + port: 18074 + source: 189.27.156.82 + mask: 24 + note: test + status: null + created_at: null + updated_at: null + - + id: null + server_id: null + type: allow + protocol: tcp + port: 41088 + source: 86.177.121.87 + mask: 24 + note: test + status: null + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + server_id: + type: string + example: null + type: + type: string + example: allow + protocol: + type: string + example: tcp + port: + type: integer + example: 18074 + source: + type: string + example: 189.27.156.82 + mask: + type: integer + example: 24 + note: + type: string + example: test + status: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - firewall-rules + post: + summary: create + operationId: create + description: 'Create a new firewall rule.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + type: allow + protocol: tcp + port: 61992 + source: 47.222.76.48 + mask: 24 + note: test + status: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + type: + type: string + example: allow + protocol: + type: string + example: tcp + port: + type: integer + example: 61992 + source: + type: string + example: 47.222.76.48 + mask: + type: integer + example: 24 + note: + type: string + example: test + status: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - firewall-rules + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + type: + type: string + description: '' + example: allow + nullable: false + enum: + - allow + - deny + protocol: + type: string + description: '' + example: udp + nullable: false + enum: + - tcp + - udp + port: + type: string + description: '' + example: voluptates + nullable: false + source: + type: string + description: '' + example: saepe + nullable: false + mask: + type: string + description: 'Mask for source IP.' + example: '0' + nullable: false + required: + - type + - protocol + - port + - source + - mask + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/firewall-rules/{firewallRule_id}': + get: + summary: show + operationId: show + description: 'Get a firewall rule by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + type: allow + protocol: tcp + port: 43107 + source: 135.73.216.16 + mask: 24 + note: test + status: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + type: + type: string + example: allow + protocol: + type: string + example: tcp + port: + type: integer + example: 43107 + source: + type: string + example: 135.73.216.16 + mask: + type: integer + example: 24 + note: + type: string + example: test + status: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - firewall-rules + delete: + summary: delete + operationId: delete + description: 'Delete firewall rule.' + parameters: [] + responses: + 204: + description: '' + tags: + - firewall-rules + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: firewallRule_id + description: 'The ID of the firewallRule.' + example: 7 + required: true + schema: + type: integer + /api/health: + get: + summary: health-check + operationId: healthCheck + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + success: true + version: 2.0.0 + properties: + success: + type: boolean + example: true + version: + type: string + example: 2.0.0 + tags: + - general + security: [] + /api/projects: + get: + summary: list + operationId: list + description: 'Get all projects.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: 29 + name: 'Zachary Lueilwitz' + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 30 + name: 'Mrs. Kiarra Heller IV' + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: 29 + name: 'Zachary Lueilwitz' + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 30 + name: 'Mrs. Kiarra Heller IV' + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + items: + type: object + properties: + id: + type: integer + example: 29 + name: + type: string + example: 'Zachary Lueilwitz' + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - projects + post: + summary: create + operationId: create + description: 'Create a new project.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 29 + name: 'Hershel Spinka' + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 29 + name: + type: string + example: 'Hershel Spinka' + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - projects + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: 'The name of the project.' + example: quos + nullable: false + required: + - name + '/api/projects/{id}': + get: + summary: show + operationId: show + description: 'Get a project by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 29 + name: 'Emery Kiehn' + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 29 + name: + type: string + example: 'Emery Kiehn' + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - projects + put: + summary: update + operationId: update + description: 'Update project.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 29 + name: 'Mable Prohaska' + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 29 + name: + type: string + example: 'Mable Prohaska' + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - projects + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: 'The name of the project.' + example: ut + nullable: false + required: + - name + parameters: + - + in: path + name: id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + '/api/projects/{project_id}': + delete: + summary: delete + operationId: delete + description: 'Delete project.' + parameters: [] + responses: + 204: + description: '' + tags: + - projects + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + '/api/projects/{project_id}/server-providers': + get: + summary: list + operationId: list + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: 2 + project_id: null + global: true + name: dolor + provider: digitalocean + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 3 + project_id: null + global: true + name: enim + provider: digitalocean + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: 2 + project_id: null + global: true + name: dolor + provider: digitalocean + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 3 + project_id: null + global: true + name: enim + provider: digitalocean + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + items: + type: object + properties: + id: + type: integer + example: 2 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: dolor + provider: + type: string + example: digitalocean + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - server-providers + post: + summary: create + operationId: create + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 2 + project_id: null + global: true + name: eligendi + provider: aws + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 2 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: eligendi + provider: + type: string + example: aws + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - server-providers + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + provider: + type: string + description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)' + example: autem + nullable: false + name: + type: string + description: 'The name of the server provider.' + example: enim + nullable: false + token: + type: string + description: 'The token if provider requires api token' + example: culpa + nullable: false + key: + type: string + description: 'The key if provider requires key' + example: sit + nullable: false + secret: + type: string + description: 'The secret if provider requires key' + example: voluptates + nullable: false + required: + - provider + - name + - token + - key + - secret + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + '/api/projects/{project_id}/server-providers/{serverProvider_id}': + get: + summary: show + operationId: show + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 2 + project_id: null + global: true + name: architecto + provider: digitalocean + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 2 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: architecto + provider: + type: string + example: digitalocean + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - server-providers + put: + summary: update + operationId: update + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 2 + project_id: null + global: true + name: reiciendis + provider: hetzner + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 2 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: reiciendis + provider: + type: string + example: hetzner + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - server-providers + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: 'The name of the server provider.' + example: minus + nullable: false + global: + type: string + description: 'Accessible in all projects' + example: false + nullable: false + enum: + - true + - false + required: + - name + - global + delete: + summary: delete + operationId: delete + description: '' + parameters: [] + responses: + 204: + description: '' + tags: + - server-providers + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: serverProvider_id + description: 'The ID of the serverProvider.' + example: 1 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers': + get: + summary: list + operationId: list + description: 'Get all servers in a project.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + project_id: null + user_id: null + provider_id: null + name: 'Dorthy Toy' + ssh_user: vito + ip: 172.132.95.155 + local_ip: 118.57.197.65 + port: 22 + os: ubuntu_22 + type: regular + type_data: null + provider: custom + provider_data: null + public_key: test + status: ready + auto_update: null + available_updates: 0 + security_updates: null + progress: 100 + progress_step: null + updates: null + last_update_check: null + created_at: null + updated_at: null + - + id: null + project_id: null + user_id: null + provider_id: null + name: 'Carrie Sporer' + ssh_user: vito + ip: 184.242.162.173 + local_ip: 135.244.50.22 + port: 22 + os: ubuntu_22 + type: regular + type_data: null + provider: custom + provider_data: null + public_key: test + status: ready + auto_update: null + available_updates: 0 + security_updates: null + progress: 100 + progress_step: null + updates: null + last_update_check: null + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + project_id: null + user_id: null + provider_id: null + name: 'Dorthy Toy' + ssh_user: vito + ip: 172.132.95.155 + local_ip: 118.57.197.65 + port: 22 + os: ubuntu_22 + type: regular + type_data: null + provider: custom + provider_data: null + public_key: test + status: ready + auto_update: null + available_updates: 0 + security_updates: null + progress: 100 + progress_step: null + updates: null + last_update_check: null + created_at: null + updated_at: null + - + id: null + project_id: null + user_id: null + provider_id: null + name: 'Carrie Sporer' + ssh_user: vito + ip: 184.242.162.173 + local_ip: 135.244.50.22 + port: 22 + os: ubuntu_22 + type: regular + type_data: null + provider: custom + provider_data: null + public_key: test + status: ready + auto_update: null + available_updates: 0 + security_updates: null + progress: 100 + progress_step: null + updates: null + last_update_check: null + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + project_id: + type: string + example: null + user_id: + type: string + example: null + provider_id: + type: string + example: null + name: + type: string + example: 'Dorthy Toy' + ssh_user: + type: string + example: vito + ip: + type: string + example: 172.132.95.155 + local_ip: + type: string + example: 118.57.197.65 + port: + type: integer + example: 22 + os: + type: string + example: ubuntu_22 + type: + type: string + example: regular + type_data: + type: string + example: null + provider: + type: string + example: custom + provider_data: + type: string + example: null + public_key: + type: string + example: test + status: + type: string + example: ready + auto_update: + type: string + example: null + available_updates: + type: integer + example: 0 + security_updates: + type: string + example: null + progress: + type: integer + example: 100 + progress_step: + type: string + example: null + updates: + type: string + example: null + last_update_check: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - servers + post: + summary: create + operationId: create + description: 'Create a new server.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + project_id: null + user_id: null + provider_id: null + name: 'Flo Beer PhD' + ssh_user: vito + ip: 168.238.14.230 + local_ip: 40.232.73.41 + port: 22 + os: ubuntu_22 + type: regular + type_data: null + provider: custom + provider_data: null + public_key: test + status: ready + auto_update: null + available_updates: 0 + security_updates: null + progress: 100 + progress_step: null + updates: null + last_update_check: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + project_id: + type: string + example: null + user_id: + type: string + example: null + provider_id: + type: string + example: null + name: + type: string + example: 'Flo Beer PhD' + ssh_user: + type: string + example: vito + ip: + type: string + example: 168.238.14.230 + local_ip: + type: string + example: 40.232.73.41 + port: + type: integer + example: 22 + os: + type: string + example: ubuntu_22 + type: + type: string + example: regular + type_data: + type: string + example: null + provider: + type: string + example: custom + provider_data: + type: string + example: null + public_key: + type: string + example: test + status: + type: string + example: ready + auto_update: + type: string + example: null + available_updates: + type: integer + example: 0 + security_updates: + type: string + example: null + progress: + type: integer + example: 100 + progress_step: + type: string + example: null + updates: + type: string + example: null + last_update_check: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - servers + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + provider: + type: string + description: 'The server provider type' + example: et + nullable: false + server_provider: + type: string + description: 'If the provider is not custom, the ID of the server provider profile' + example: digitalocean + nullable: false + enum: + - custom + - hetzner + - digitalocean + - linode + - vultr + region: + type: string + description: 'Provider region if the provider is not custom' + example: inventore + nullable: false + plan: + type: string + description: 'Provider plan if the provider is not custom' + example: atque + nullable: false + ip: + type: string + description: 'SSH IP address if the provider is custom' + example: quam + nullable: false + port: + type: string + description: 'SSH Port if the provider is custom' + example: nemo + nullable: false + name: + type: string + description: 'The name of the server.' + example: perspiciatis + nullable: false + os: + type: string + description: 'The os of the server' + example: similique + nullable: false + type: + type: string + description: 'Server type' + example: regular + nullable: false + enum: + - regular + - database + webserver: + type: string + description: 'Web server' + example: none + nullable: false + enum: + - none + - nginx + database: + type: string + description: Database + example: none + nullable: false + enum: + - none + - mysql57 + - mysql80 + - mariadb103 + - mariadb104 + - mariadb103 + - postgresql12 + - postgresql13 + - postgresql14 + - postgresql15 + - postgresql16 + php: + type: string + description: 'PHP version' + example: '8.1' + nullable: false + enum: + - '7.0' + - '7.1' + - '7.2' + - '7.3' + - '7.4' + - '8.0' + - '8.1' + - '8.2' + - '8.3' + required: + - provider + - server_provider + - region + - plan + - ip + - port + - name + - os + - type + - webserver + - database + - php + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{id}': + get: + summary: show + operationId: show + description: 'Get a server by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + project_id: null + user_id: null + provider_id: null + name: 'Stephany Ankunding' + ssh_user: vito + ip: 145.28.94.46 + local_ip: 69.133.44.100 + port: 22 + os: ubuntu_22 + type: regular + type_data: null + provider: custom + provider_data: null + public_key: test + status: ready + auto_update: null + available_updates: 0 + security_updates: null + progress: 100 + progress_step: null + updates: null + last_update_check: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + project_id: + type: string + example: null + user_id: + type: string + example: null + provider_id: + type: string + example: null + name: + type: string + example: 'Stephany Ankunding' + ssh_user: + type: string + example: vito + ip: + type: string + example: 145.28.94.46 + local_ip: + type: string + example: 69.133.44.100 + port: + type: integer + example: 22 + os: + type: string + example: ubuntu_22 + type: + type: string + example: regular + type_data: + type: string + example: null + provider: + type: string + example: custom + provider_data: + type: string + example: null + public_key: + type: string + example: test + status: + type: string + example: ready + auto_update: + type: string + example: null + available_updates: + type: integer + example: 0 + security_updates: + type: string + example: null + progress: + type: integer + example: 100 + progress_step: + type: string + example: null + updates: + type: string + example: null + last_update_check: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - servers + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/reboot': + post: + summary: reboot + operationId: reboot + description: 'Reboot a server.' + parameters: [] + responses: + 204: + description: '' + tags: + - servers + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/upgrade': + post: + summary: upgrade + operationId: upgrade + description: 'Upgrade server.' + parameters: [] + responses: + 204: + description: '' + tags: + - servers + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}': + delete: + summary: delete + operationId: delete + description: 'Delete server.' + parameters: [] + responses: + 204: + description: '' + tags: + - servers + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services': + get: + summary: list + operationId: list + description: 'Get all services.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + server_id: null + type: null + type_data: null + name: null + version: null + unit: null + status: null + is_default: null + created_at: null + updated_at: null + - + id: null + server_id: null + type: null + type_data: null + name: null + version: null + unit: null + status: null + is_default: null + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + server_id: null + type: null + type_data: null + name: null + version: null + unit: null + status: null + is_default: null + created_at: null + updated_at: null + - + id: null + server_id: null + type: null + type_data: null + name: null + version: null + unit: null + status: null + is_default: null + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + server_id: + type: string + example: null + type: + type: string + example: null + type_data: + type: string + example: null + name: + type: string + example: null + version: + type: string + example: null + unit: + type: string + example: null + status: + type: string + example: null + is_default: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services/{id}': + get: + summary: show + operationId: show + description: 'Get a service by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + type: null + type_data: null + name: null + version: null + unit: null + status: null + is_default: null + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + type: + type: string + example: null + type_data: + type: string + example: null + name: + type: string + example: null + version: + type: string + example: null + unit: + type: string + example: null + status: + type: string + example: null + is_default: + type: string + example: null + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: id + description: 'The ID of the service.' + example: 27 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services/{service_id}/start': + post: + summary: start + operationId: start + description: 'Start service.' + parameters: [] + responses: + 204: + description: '' + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: service_id + description: 'The ID of the service.' + example: 27 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services/{service_id}/stop': + post: + summary: stop + operationId: stop + description: 'Stop service.' + parameters: [] + responses: + 204: + description: '' + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: service_id + description: 'The ID of the service.' + example: 27 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services/{service_id}/restart': + post: + summary: restart + operationId: restart + description: 'Restart service.' + parameters: [] + responses: + 204: + description: '' + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: service_id + description: 'The ID of the service.' + example: 27 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services/{service_id}/enable': + post: + summary: enable + operationId: enable + description: 'Enable service.' + parameters: [] + responses: + 204: + description: '' + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: service_id + description: 'The ID of the service.' + example: 27 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services/{service_id}/disable': + post: + summary: disable + operationId: disable + description: 'Disable service.' + parameters: [] + responses: + 204: + description: '' + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: service_id + description: 'The ID of the service.' + example: 27 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/services/{service_id}': + delete: + summary: delete + operationId: delete + description: 'Delete service.' + parameters: [] + responses: + 204: + description: '' + tags: + - services + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: service_id + description: 'The ID of the service.' + example: 27 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/sites': + get: + summary: list + operationId: list + description: 'Get all sites.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + server_id: null + source_control_id: null + type: laravel + type_data: null + domain: test.com + aliases: null + web_directory: / + path: /home + php_version: '8.2' + repository: null + branch: main + status: ready + port: null + progress: 100 + created_at: null + updated_at: null + - + id: null + server_id: null + source_control_id: null + type: laravel + type_data: null + domain: test.com + aliases: null + web_directory: / + path: /home + php_version: '8.2' + repository: null + branch: main + status: ready + port: null + progress: 100 + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + server_id: null + source_control_id: null + type: laravel + type_data: null + domain: test.com + aliases: null + web_directory: / + path: /home + php_version: '8.2' + repository: null + branch: main + status: ready + port: null + progress: 100 + created_at: null + updated_at: null + - + id: null + server_id: null + source_control_id: null + type: laravel + type_data: null + domain: test.com + aliases: null + web_directory: / + path: /home + php_version: '8.2' + repository: null + branch: main + status: ready + port: null + progress: 100 + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + server_id: + type: string + example: null + source_control_id: + type: string + example: null + type: + type: string + example: laravel + type_data: + type: string + example: null + domain: + type: string + example: test.com + aliases: + type: string + example: null + web_directory: + type: string + example: / + path: + type: string + example: /home + php_version: + type: string + example: '8.2' + repository: + type: string + example: null + branch: + type: string + example: main + status: + type: string + example: ready + port: + type: string + example: null + progress: + type: integer + example: 100 + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - sites + post: + summary: create + operationId: create + description: 'Create a new site.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + source_control_id: null + type: laravel + type_data: null + domain: test.com + aliases: null + web_directory: / + path: /home + php_version: '8.2' + repository: null + branch: main + status: ready + port: null + progress: 100 + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + source_control_id: + type: string + example: null + type: + type: string + example: laravel + type_data: + type: string + example: null + domain: + type: string + example: test.com + aliases: + type: string + example: null + web_directory: + type: string + example: / + path: + type: string + example: /home + php_version: + type: string + example: '8.2' + repository: + type: string + example: null + branch: + type: string + example: main + status: + type: string + example: ready + port: + type: string + example: null + progress: + type: integer + example: 100 + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - sites + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + type: + type: string + description: '' + example: wordpress + nullable: false + enum: + - php + - php-blank + - phpmyadmin + - laravel + - wordpress + domain: + type: string + description: '' + example: quo + nullable: false + aliases: + type: array + description: '' + example: + - dolorum + items: + type: string + php_version: + type: string + description: 'One of the installed PHP Versions' + example: '7.4' + nullable: false + web_directory: + type: string + description: 'Required for PHP and Laravel sites' + example: public + nullable: false + source_control: + type: string + description: 'Source control ID, Required for Sites which support source control' + example: explicabo + nullable: false + repository: + type: string + description: 'Repository, Required for Sites which support source control' + example: organization/repository + nullable: false + branch: + type: string + description: 'Branch, Required for Sites which support source control' + example: main + nullable: false + composer: + type: boolean + description: 'Run composer if site supports composer' + example: true + nullable: false + version: + type: string + description: 'Version, if the site type requires a version like PHPMyAdmin' + example: 5.2.1 + nullable: false + required: + - type + - domain + - aliases + - php_version + - web_directory + - source_control + - repository + - branch + - composer + - version + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/sites/{id}': + get: + summary: show + operationId: show + description: 'Get a site by ID.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + server_id: null + source_control_id: null + type: laravel + type_data: null + domain: test.com + aliases: null + web_directory: / + path: /home + php_version: '8.2' + repository: null + branch: main + status: ready + port: null + progress: 100 + created_at: null + updated_at: null + properties: + id: + type: string + example: null + server_id: + type: string + example: null + source_control_id: + type: string + example: null + type: + type: string + example: laravel + type_data: + type: string + example: null + domain: + type: string + example: test.com + aliases: + type: string + example: null + web_directory: + type: string + example: / + path: + type: string + example: /home + php_version: + type: string + example: '8.2' + repository: + type: string + example: null + branch: + type: string + example: main + status: + type: string + example: ready + port: + type: string + example: null + progress: + type: integer + example: 100 + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - sites + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: id + description: 'The ID of the site.' + example: 8 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/sites/{site_id}': + delete: + summary: delete + operationId: delete + description: 'Delete site.' + parameters: [] + responses: + 204: + description: '' + tags: + - sites + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: site_id + description: 'The ID of the site.' + example: 8 + required: true + schema: + type: integer + '/api/projects/{project_id}/source-controls': + get: + summary: list + operationId: list + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: 5 + project_id: null + global: true + name: 'Jaiden Kling' + provider: github + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 6 + project_id: null + global: true + name: 'Ms. Brianne Bosco' + provider: github + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: 5 + project_id: null + global: true + name: 'Jaiden Kling' + provider: github + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 6 + project_id: null + global: true + name: 'Ms. Brianne Bosco' + provider: github + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + items: + type: object + properties: + id: + type: integer + example: 5 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: 'Jaiden Kling' + provider: + type: string + example: github + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - source-controls + post: + summary: create + operationId: create + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 5 + project_id: null + global: true + name: 'Toby Parker' + provider: github + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 5 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: 'Toby Parker' + provider: + type: string + example: github + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - source-controls + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + provider: + type: string + description: 'The provider' + example: bitbucket + nullable: false + enum: + - gitlab + - github + - bitbucket + name: + type: string + description: 'The name of the storage provider.' + example: eos + nullable: false + token: + type: string + description: 'The token if provider requires api token' + example: et + nullable: false + url: + type: string + description: 'The URL if the provider is Gitlab and it is self-hosted' + example: 'https://lueilwitz.com/nostrum-et-porro-atque-sint.html' + nullable: false + username: + type: string + description: 'The username if the provider is Bitbucket' + example: consectetur + nullable: false + password: + type: string + description: 'The password if the provider is Bitbucket' + example: 'PL.P?{06\ECi0' + nullable: false + required: + - provider + - name + - token + - url + - username + - password + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + '/api/projects/{project_id}/source-controls/{sourceControl_id}': + get: + summary: show + operationId: show + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 5 + project_id: null + global: true + name: 'Prof. Bartholome Graham IV' + provider: github + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 5 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: 'Prof. Bartholome Graham IV' + provider: + type: string + example: github + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - source-controls + put: + summary: update + operationId: update + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 5 + project_id: null + global: true + name: 'Cicero Smitham' + provider: github + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 5 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: 'Cicero Smitham' + provider: + type: string + example: github + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - source-controls + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: 'The name of the storage provider.' + example: quaerat + nullable: false + token: + type: string + description: 'The token if provider requires api token' + example: consectetur + nullable: false + url: + type: string + description: 'The URL if the provider is Gitlab and it is self-hosted' + example: 'http://www.hudson.biz/rerum-voluptatem-debitis-accusamus' + nullable: false + username: + type: string + description: 'The username if the provider is Bitbucket' + example: voluptatem + nullable: false + password: + type: string + description: 'The password if the provider is Bitbucket' + example: '\p/el>)3#~E?kI' + nullable: false + global: + type: string + description: 'Accessible in all projects' + example: false + nullable: false + enum: + - true + - false + required: + - name + - token + - url + - username + - password + - global + delete: + summary: delete + operationId: delete + description: '' + parameters: [] + responses: + 204: + description: '' + tags: + - source-controls + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: sourceControl_id + description: 'The ID of the sourceControl.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/ssh-keys': + get: + summary: list + operationId: list + description: 'Get all ssh keys.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: null + user: null + name: 'Dr. Reanna Braun' + created_at: null + updated_at: null + - + id: null + user: null + name: 'Norene Fritsch' + created_at: null + updated_at: null + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: null + user: null + name: 'Dr. Reanna Braun' + created_at: null + updated_at: null + - + id: null + user: null + name: 'Norene Fritsch' + created_at: null + updated_at: null + items: + type: object + properties: + id: + type: string + example: null + user: + type: string + example: null + name: + type: string + example: 'Dr. Reanna Braun' + created_at: + type: string + example: null + updated_at: + type: string + example: null + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - ssh-keys + post: + summary: create + operationId: create + description: 'Deploy ssh key to server.' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: null + user: null + name: "Sophia D'Amore" + created_at: null + updated_at: null + properties: + id: + type: string + example: null + user: + type: string + example: null + name: + type: string + example: "Sophia D'Amore" + created_at: + type: string + example: null + updated_at: + type: string + example: null + tags: + - ssh-keys + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + key_id: + type: string + description: 'The ID of the key.' + example: vero + nullable: false + name: + type: string + description: 'Key name, required if key_id is not provided.' + example: voluptates + nullable: false + public_key: + type: string + description: 'Public Key, required if key_id is not provided.' + example: dolor + nullable: false + required: + - key_id + - name + - public_key + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + '/api/projects/{project_id}/servers/{server_id}/ssh-keys/{sshKey_id}': + delete: + summary: delete + operationId: delete + description: 'Delete ssh key from server.' + parameters: [] + responses: + 204: + description: '' + tags: + - ssh-keys + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: server_id + description: 'The ID of the server.' + example: 3 + required: true + schema: + type: integer + - + in: path + name: sshKey_id + description: 'The ID of the sshKey.' + example: 4 + required: true + schema: + type: integer + '/api/projects/{project_id}/storage-providers': + get: + summary: list + operationId: list + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + data: + - + id: 3 + project_id: null + global: true + name: et + provider: local + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 4 + project_id: null + global: true + name: sed + provider: local + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + links: + first: '/?page=1' + last: '/?page=1' + prev: null + next: null + meta: + current_page: 1 + from: 1 + last_page: 1 + links: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + path: / + per_page: 25 + to: 2 + total: 2 + properties: + data: + type: array + example: + - + id: 3 + project_id: null + global: true + name: et + provider: local + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + - + id: 4 + project_id: null + global: true + name: sed + provider: local + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + items: + type: object + properties: + id: + type: integer + example: 3 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: et + provider: + type: string + example: local + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + links: + type: object + properties: + first: + type: string + example: '/?page=1' + last: + type: string + example: '/?page=1' + prev: + type: string + example: null + next: + type: string + example: null + meta: + type: object + properties: + current_page: + type: integer + example: 1 + from: + type: integer + example: 1 + last_page: + type: integer + example: 1 + links: + type: array + example: + - + url: null + label: '« Previous' + active: false + - + url: '/?page=1' + label: '1' + active: true + - + url: null + label: 'Next »' + active: false + items: + type: object + properties: + url: + type: string + example: null + label: + type: string + example: '« Previous' + active: + type: boolean + example: false + path: + type: string + example: / + per_page: + type: integer + example: 25 + to: + type: integer + example: 2 + total: + type: integer + example: 2 + tags: + - storage-providers + post: + summary: create + operationId: create + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 3 + project_id: null + global: true + name: est + provider: dropbox + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 3 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: est + provider: + type: string + example: dropbox + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - storage-providers + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + provider: + type: string + description: 'The provider (aws, linode, hetzner, digitalocean, vultr, ...)' + example: quod + nullable: false + name: + type: string + description: 'The name of the storage provider.' + example: commodi + nullable: false + token: + type: string + description: 'The token if provider requires api token' + example: ipsum + nullable: false + key: + type: string + description: 'The key if provider requires key' + example: ratione + nullable: false + secret: + type: string + description: 'The secret if provider requires key' + example: iste + nullable: false + required: + - provider + - name + - token + - key + - secret + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + '/api/projects/{project_id}/storage-providers/{storageProvider_id}': + get: + summary: show + operationId: show + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 3 + project_id: null + global: true + name: officia + provider: ftp + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 3 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: officia + provider: + type: string + example: ftp + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - storage-providers + put: + summary: update + operationId: update + description: '' + parameters: [] + responses: + 200: + description: '' + content: + application/json: + schema: + type: object + example: + id: 3 + project_id: null + global: true + name: rerum + provider: ftp + created_at: '2024-11-01T15:40:48.000000Z' + updated_at: '2024-11-01T15:40:48.000000Z' + properties: + id: + type: integer + example: 3 + project_id: + type: string + example: null + global: + type: boolean + example: true + name: + type: string + example: rerum + provider: + type: string + example: ftp + created_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + updated_at: + type: string + example: '2024-11-01T15:40:48.000000Z' + tags: + - storage-providers + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: 'The name of the storage provider.' + example: iusto + nullable: false + global: + type: string + description: 'Accessible in all projects' + example: true + nullable: false + enum: + - true + - false + required: + - name + - global + delete: + summary: delete + operationId: delete + description: '' + parameters: [] + responses: + 204: + description: '' + tags: + - storage-providers + parameters: + - + in: path + name: project_id + description: 'The ID of the project.' + example: 1 + required: true + schema: + type: integer + - + in: path + name: storageProvider_id + description: 'The ID of the storageProvider.' + example: 1 + required: true + schema: + type: integer +tags: + - + name: cron-jobs + description: '' + - + name: database-users + description: '' + - + name: databases + description: '' + - + name: firewall-rules + description: '' + - + name: general + description: '' + - + name: projects + description: '' + - + name: server-providers + description: '' + - + name: servers + description: '' + - + name: services + description: '' + - + name: sites + description: '' + - + name: source-controls + description: '' + - + name: ssh-keys + description: '' + - + name: storage-providers + description: '' +components: + securitySchemes: + default: + type: http + scheme: bearer + description: 'You can retrieve your token by visiting here' +security: + - + default: [] diff --git a/resources/svg/plug.svg b/resources/svg/plug.svg new file mode 100644 index 0000000..1dc0f5d --- /dev/null +++ b/resources/svg/plug.svg @@ -0,0 +1,6 @@ + + + + diff --git a/routes/api.php b/routes/api.php index 377de32..b3d9bbc 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,13 +1 @@ name('api.health'); -Route::any('git-hooks', GitHookController::class)->name('api.git-hooks'); - -Route::post('servers/{server}/agent/{id}', AgentController::class)->name('api.servers.agent'); diff --git a/routes/web.php b/routes/web.php index 1a7c3e0..b3d9bbc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,8 +1 @@ group(function () { - Route::post('/{server}/console', [ConsoleController::class, 'run'])->name('servers.console.run'); -}); diff --git a/tests/Feature/API/CronjobTest.php b/tests/Feature/API/CronjobTest.php new file mode 100644 index 0000000..d548966 --- /dev/null +++ b/tests/Feature/API/CronjobTest.php @@ -0,0 +1,79 @@ +user, ['read', 'write']); + + /** @var CronJob $cronjob */ + $cronjob = CronJob::factory()->create([ + 'server_id' => $this->server->id, + ]); + + $this->json('GET', route('api.projects.servers.cron-jobs', [ + 'project' => $this->server->project, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'command' => $cronjob->command, + 'frequency' => $cronjob->frequency, + ]); + } + + public function test_create_cronjob() + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + $this->json('POST', route('api.projects.servers.cron-jobs.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), [ + 'command' => 'ls -la', + 'user' => 'vito', + 'frequency' => '* * * * *', + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'command' => 'ls -la', + 'user' => 'vito', + 'frequency' => '* * * * *', + 'status' => CronjobStatus::READY, + ]); + } + + public function test_delete_cronjob() + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var CronJob $cronjob */ + $cronjob = CronJob::factory()->create([ + 'server_id' => $this->server->id, + 'user' => 'vito', + ]); + + $this->json('DELETE', route('api.projects.servers.cron-jobs.delete', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'cronJob' => $cronjob, + ])) + ->assertSuccessful() + ->assertNoContent(); + } +} diff --git a/tests/Feature/API/DatabaseTest.php b/tests/Feature/API/DatabaseTest.php new file mode 100644 index 0000000..8fdfee0 --- /dev/null +++ b/tests/Feature/API/DatabaseTest.php @@ -0,0 +1,93 @@ +user, ['read', 'write']); + + SSH::fake(); + + $this->json('POST', route('api.projects.servers.databases.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), [ + 'name' => 'database', + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => 'database', + 'status' => DatabaseStatus::READY, + ]); + } + + public function test_show_database(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var Database $database */ + $database = Database::factory()->create([ + 'server_id' => $this->server, + ]); + + $this->json('GET', route('api.projects.servers.databases.show', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'database' => $database, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => $database->name, + ]); + } + + public function test_see_databases_list(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var Database $database */ + $database = Database::factory()->create([ + 'server_id' => $this->server, + ]); + + $this->json('GET', route('api.projects.servers.databases', [ + 'project' => $this->server->project, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => $database->name, + ]); + } + + public function test_delete_database(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + SSH::fake(); + + /** @var Database $database */ + $database = Database::factory()->create([ + 'server_id' => $this->server, + ]); + + $this->json('DELETE', route('api.projects.servers.databases.delete', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'database' => $database, + ])) + ->assertSuccessful() + ->assertNoContent(); + } +} diff --git a/tests/Feature/API/DatabaseUserTest.php b/tests/Feature/API/DatabaseUserTest.php new file mode 100644 index 0000000..7a8aef5 --- /dev/null +++ b/tests/Feature/API/DatabaseUserTest.php @@ -0,0 +1,146 @@ +user, ['read', 'write']); + + SSH::fake(); + + $this->json('POST', route('api.projects.servers.database-users.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), [ + 'username' => 'user', + 'password' => 'password', + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'username' => 'user', + 'status' => DatabaseUserStatus::READY, + ]); + } + + public function test_create_database_user_with_remote(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + SSH::fake(); + + $this->json('POST', route('api.projects.servers.database-users.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), [ + 'username' => 'user', + 'password' => 'password', + 'host' => '%', + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'username' => 'user', + 'host' => '%', + 'status' => DatabaseUserStatus::READY, + ]); + } + + public function test_see_database_users_list(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var DatabaseUser $databaseUser */ + $databaseUser = DatabaseUser::factory()->create([ + 'server_id' => $this->server, + ]); + + $this->json('GET', route('api.projects.servers.database-users', [ + 'project' => $this->server->project, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'username' => $databaseUser->username, + ]); + } + + public function test_show_database_user(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var DatabaseUser $databaseUser */ + $databaseUser = DatabaseUser::factory()->create([ + 'server_id' => $this->server, + ]); + + $this->json('GET', route('api.projects.servers.database-users.show', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'databaseUser' => $databaseUser, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'username' => $databaseUser->username, + ]); + } + + public function test_link_database(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + SSH::fake(); + + /** @var Database $database */ + $database = Database::factory()->create([ + 'server_id' => $this->server, + ]); + + /** @var DatabaseUser $databaseUser */ + $databaseUser = DatabaseUser::factory()->create([ + 'server_id' => $this->server, + ]); + + $this->json('POST', route('api.projects.servers.database-users.link', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'databaseUser' => $databaseUser, + ]), [ + 'databases' => [$database->name], + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'username' => $databaseUser->username, + 'databases' => [$database->name], + ]); + } + + public function test_delete_database_user(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + SSH::fake(); + + /** @var DatabaseUser $databaseUser */ + $databaseUser = DatabaseUser::factory()->create([ + 'server_id' => $this->server, + ]); + + $this->json('DELETE', route('api.projects.servers.database-users.delete', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'databaseUser' => $databaseUser, + ])) + ->assertNoContent(); + } +} diff --git a/tests/Feature/API/FirewallTest.php b/tests/Feature/API/FirewallTest.php new file mode 100644 index 0000000..7d3eb89 --- /dev/null +++ b/tests/Feature/API/FirewallTest.php @@ -0,0 +1,77 @@ +user, ['read', 'write']); + + $this->json('POST', route('api.projects.servers.firewall-rules.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), [ + 'type' => 'allow', + 'protocol' => 'tcp', + 'port' => '1234', + 'source' => '0.0.0.0', + 'mask' => '0', + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'port' => 1234, + 'status' => FirewallRuleStatus::READY, + ]); + } + + public function test_see_firewall_rules(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var FirewallRule $rule */ + $rule = FirewallRule::factory()->create([ + 'server_id' => $this->server->id, + ]); + + $this->json('GET', route('api.projects.servers.firewall-rules', [ + 'project' => $this->server->project, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'source' => $rule->source, + 'port' => $rule->port, + ]); + } + + public function test_delete_firewall_rule(): void + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var FirewallRule $rule */ + $rule = FirewallRule::factory()->create([ + 'server_id' => $this->server->id, + ]); + + $this->json('DELETE', route('api.projects.servers.firewall-rules.delete', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'firewallRule' => $rule, + ])) + ->assertNoContent(); + } +} diff --git a/tests/Feature/API/ProjectsTest.php b/tests/Feature/API/ProjectsTest.php new file mode 100644 index 0000000..43e358f --- /dev/null +++ b/tests/Feature/API/ProjectsTest.php @@ -0,0 +1,94 @@ +user, ['read', 'write']); + + $this->json('POST', '/api/projects', [ + 'name' => 'test', + ]) + ->assertSuccessful(); + + $this->assertDatabaseHas('projects', [ + 'name' => 'test', + ]); + } + + public function test_see_projects_list(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $project = Project::factory()->create(); + + $this->user->projects()->attach($project); + + $this->json('GET', '/api/projects') + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => $project->name, + ]); + } + + public function test_delete_project(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $project = Project::factory()->create(); + + $this->user->projects()->attach($project); + + Livewire::test(Settings::class, [ + 'project' => $project, + ]) + ->callAction('delete') + ->assertSuccessful(); + + $this->assertDatabaseMissing('projects', [ + 'id' => $project->id, + ]); + } + + public function test_edit_project(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $project = Project::factory()->create(); + + $this->user->projects()->attach($project); + + $this->json('PUT', "/api/projects/{$project->id}", [ + 'name' => 'new-name', + ]) + ->assertSuccessful(); + + $this->assertDatabaseHas('projects', [ + 'id' => $project->id, + 'name' => 'new-name', + ]); + } + + public function test_cannot_delete_last_project(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $this->json('DELETE', "/api/projects/{$this->user->currentProject->id}") + ->assertJsonValidationErrorFor('project'); + + $this->assertDatabaseHas('projects', [ + 'id' => $this->user->currentProject->id, + ]); + } +} diff --git a/tests/Feature/API/ServerProvidersTest.php b/tests/Feature/API/ServerProvidersTest.php new file mode 100644 index 0000000..7d4ab01 --- /dev/null +++ b/tests/Feature/API/ServerProvidersTest.php @@ -0,0 +1,174 @@ +user, ['read', 'write']); + + Http::fake(); + + $data = array_merge( + [ + 'provider' => $provider, + 'name' => 'profile', + ], + $input + ); + $this->json('POST', route('api.projects.server-providers.create', [ + 'project' => $this->user->current_project_id, + ]), $data) + ->assertSuccessful() + ->assertJsonFragment([ + 'provider' => $provider, + 'name' => 'profile', + 'project_id' => isset($input['global']) ? null : $this->user->current_project_id, + ]); + } + + /** + * @dataProvider data + */ + public function test_cannot_connect_to_provider(string $provider, array $input): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + Http::fake([ + '*' => Http::response([], 401), + ]); + + $data = array_merge( + [ + 'provider' => $provider, + 'name' => 'profile', + ], + $input + ); + $this->json('POST', route('api.projects.server-providers.create', [ + 'project' => $this->user->current_project_id, + ]), $data) + ->assertJsonValidationErrorFor('provider'); + } + + public function test_see_providers_list(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var \App\Models\ServerProvider $provider */ + $provider = \App\Models\ServerProvider::factory()->create([ + 'user_id' => $this->user->id, + ]); + + $this->json('GET', route('api.projects.server-providers', [ + 'project' => $this->user->current_project_id, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'id' => $provider->id, + 'provider' => $provider->provider, + ]); + } + + /** + * @dataProvider data + */ + public function test_delete_provider(string $provider): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var \App\Models\ServerProvider $provider */ + $provider = \App\Models\ServerProvider::factory()->create([ + 'user_id' => $this->user->id, + 'provider' => $provider, + ]); + + $this->json('DELETE', route('api.projects.server-providers.delete', [ + 'project' => $this->user->current_project_id, + 'serverProvider' => $provider->id, + ])) + ->assertNoContent(); + } + + /** + * @dataProvider data + */ + public function test_cannot_delete_provider(string $provider): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var \App\Models\ServerProvider $provider */ + $provider = \App\Models\ServerProvider::factory()->create([ + 'user_id' => $this->user->id, + 'provider' => $provider, + ]); + + $this->server->update([ + 'provider_id' => $provider->id, + ]); + + $this->json('DELETE', route('api.projects.server-providers.delete', [ + 'project' => $this->user->current_project_id, + 'serverProvider' => $provider->id, + ])) + ->assertJsonValidationErrors([ + 'provider' => 'This server provider is being used by a server.', + ]); + } + + public static function data(): array + { + return [ + // [ + // ServerProvider::AWS, + // [ + // 'key' => 'key', + // 'secret' => 'secret', + // ], + // ], + [ + ServerProvider::LINODE, + [ + 'token' => 'token', + ], + ], + [ + ServerProvider::LINODE, + [ + 'token' => 'token', + 'global' => 1, + ], + ], + [ + ServerProvider::DIGITALOCEAN, + [ + 'token' => 'token', + ], + ], + [ + ServerProvider::VULTR, + [ + 'token' => 'token', + ], + ], + [ + ServerProvider::HETZNER, + [ + 'token' => 'token', + ], + ], + ]; + } +} diff --git a/tests/Feature/API/ServerSshKeysTest.php b/tests/Feature/API/ServerSshKeysTest.php new file mode 100644 index 0000000..aea1a99 --- /dev/null +++ b/tests/Feature/API/ServerSshKeysTest.php @@ -0,0 +1,109 @@ +user, ['read', 'write']); + + $sshKey = SshKey::factory()->create([ + 'user_id' => $this->user->id, + 'name' => 'My first key', + 'public_key' => 'public-key-content', + ]); + + $this->server->sshKeys()->attach($sshKey, [ + 'status' => SshKeyStatus::ADDED, + ]); + + $this->json('GET', route('api.projects.servers.ssh-keys', [ + 'project' => $this->server->project, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => 'My first key', + ]); + } + + public function test_add_new_ssh_key() + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + $this->json('POST', route('api.projects.servers.ssh-keys.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), [ + 'name' => 'My first key', + 'public_key' => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3CCnyBbpCgOJ0AWUSfBZ+mYAsYzcQDegPkBx1kyE0bXT1yX4+6uYx1Jh6NxWgLyaU0BaP4nsClrK1u5FojQHd8J7ycc0N3H8B+v2NPzj1Q6bFnl40saastONVm+d4edbCg9BowGAafLcf9ALsognqqOWQbK/QOpAhg25IAe47eiY3IjDGMHlsvaZkMtkDhT4t1mK8ZLjxw5vjyVYgINJefR981bIxMFrXy+0xBCsYOZxMIoAJsgCkrAGlI4kQHKv0SQVccSyTE1eziIZa5b3QUlXj8ogxMfK/EOD7Aoqinw652k4S5CwFs/LLmjWcFqCKDM6CSggWpB78DZ729O6zFvQS9V99/9SsSV7Qc5ML7B0DKzJ/tbHkaAE8xdZnQnZFVUegUMtUmjvngMaGlYsxkAZrUKsFRoh7xfXVkDyRBaBSslRNe8LFsXw9f7Q+3jdZ5vhGhmp+TBXTlgxApwR023411+ABE9y0doCx8illya3m2olEiiMZkRclgqsWFSk=', + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => 'My first key', + ]); + } + + public function test_add_existing_key() + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var SshKey $sshKey */ + $sshKey = SshKey::factory()->create([ + 'user_id' => $this->user->id, + 'name' => 'My first key', + 'public_key' => 'public-key-content', + ]); + + $this->json('POST', route('api.projects.servers.ssh-keys.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), [ + 'key_id' => $sshKey->id, + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => 'My first key', + ]); + } + + public function test_delete_ssh_key() + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var SshKey $sshKey */ + $sshKey = SshKey::factory()->create([ + 'user_id' => $this->user->id, + 'name' => 'My first key', + 'public_key' => 'public-key-content', + ]); + + $this->server->sshKeys()->attach($sshKey, [ + 'status' => SshKeyStatus::ADDED, + ]); + + $this->json('DELETE', route('api.projects.servers.ssh-keys.delete', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'sshKey' => $sshKey, + ])) + ->assertSuccessful() + ->assertNoContent(); + } +} diff --git a/tests/Feature/API/ServerTest.php b/tests/Feature/API/ServerTest.php new file mode 100644 index 0000000..d29d7ca --- /dev/null +++ b/tests/Feature/API/ServerTest.php @@ -0,0 +1,121 @@ +user, ['read', 'write']); + + $this->json('GET', route('api.projects.servers', [ + 'project' => $this->user->current_project_id, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => $this->server->name, + ]); + } + + public function test_get_server(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $this->json('GET', route('api.projects.servers.show', [ + 'project' => $this->user->current_project_id, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => $this->server->name, + ]); + } + + /** + * @dataProvider createData + */ + public function test_create_server(string $type): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + SSH::fake('Active: active'); // fake output for service installations + + $this->json('POST', route('api.projects.servers.create', [ + 'project' => $this->user->current_project_id, + ]), [ + 'type' => $type, + 'provider' => ServerProvider::CUSTOM, + 'name' => 'test', + 'ip' => '1.1.1.1', + 'port' => '22', + 'os' => OperatingSystem::UBUNTU22, + 'webserver' => Webserver::NGINX, + 'database' => Database::MYSQL80, + 'php' => '8.2', + ]) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => 'test', + 'type' => $type, + ]); + } + + public function test_delete_server(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + SSH::fake(); + + $this->json('DELETE', route('api.projects.servers.delete', [ + 'project' => $this->server->project_id, + 'server' => $this->server->id, + ])) + ->assertNoContent(); + } + + public function test_reboot_server(): void + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + $this->json('POST', route('api.projects.servers.reboot', [ + 'project' => $this->server->project_id, + 'server' => $this->server->id, + ])) + ->assertNoContent(); + } + + public function test_upgrade_server(): void + { + SSH::fake('Available updates:0'); + + Sanctum::actingAs($this->user, ['read', 'write']); + + $this->json('POST', route('api.projects.servers.upgrade', [ + 'project' => $this->server->project_id, + 'server' => $this->server->id, + ])) + ->assertNoContent(); + } + + public static function createData(): array + { + return [ + [ServerType::REGULAR], + [ServerType::DATABASE], + ]; + } +} diff --git a/tests/Feature/API/ServicesTest.php b/tests/Feature/API/ServicesTest.php new file mode 100644 index 0000000..a485dcd --- /dev/null +++ b/tests/Feature/API/ServicesTest.php @@ -0,0 +1,125 @@ +user, ['read', 'write']); + + $this->json('GET', route('api.projects.servers.services', [ + 'project' => $this->server->project, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => 'mysql', + ]) + ->assertJsonFragment([ + 'name' => 'nginx', + ]) + ->assertJsonFragment([ + 'name' => 'php', + ]) + ->assertJsonFragment([ + 'name' => 'supervisor', + ]) + ->assertJsonFragment([ + 'name' => 'redis', + ]) + ->assertJsonFragment([ + 'name' => 'ufw', + ]); + } + + public function test_show_service(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + $service = $this->server->services()->firstOrFail(); + + $this->json('GET', route('api.projects.servers.services.show', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'service' => $service, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'name' => $service->name, + ]); + } + + /** + * @dataProvider data + */ + public function test_manage_service(string $action): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $service = $this->server->services()->firstOrFail(); + $service->status = ServiceStatus::STOPPED; + $service->save(); + + SSH::fake('Active: active'); + + $this->json('POST', route('api.projects.servers.services.'.$action, [ + 'project' => $this->server->project, + 'server' => $this->server, + 'service' => $service, + ])) + ->assertSuccessful() + ->assertNoContent(); + } + + public function test_uninstall_service(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $service = $this->server->services()->where('type', 'process_manager')->firstOrFail(); + + SSH::fake(); + + $this->json('DELETE', route('api.projects.servers.services.uninstall', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'service' => $service, + ])) + ->assertSuccessful() + ->assertNoContent(); + } + + public function test_cannot_uninstall_service_because_it_is_being_used(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + $service = $this->server->services()->where('type', 'webserver')->firstOrFail(); + + SSH::fake(); + + $this->json('DELETE', route('api.projects.servers.services.uninstall', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'service' => $service, + ])) + ->assertJsonValidationErrorFor('service'); + } + + public static function data(): array + { + return [ + ['start'], + ['stop'], + ['restart'], + ['enable'], + ['disable'], + ]; + } +} diff --git a/tests/Feature/API/SitesTest.php b/tests/Feature/API/SitesTest.php new file mode 100644 index 0000000..2a38f26 --- /dev/null +++ b/tests/Feature/API/SitesTest.php @@ -0,0 +1,92 @@ + Http::response([ + ], 201), + ]); + + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var \App\Models\SourceControl $sourceControl */ + $sourceControl = \App\Models\SourceControl::factory()->create([ + 'provider' => SourceControl::GITHUB, + ]); + + $inputs['source_control'] = $sourceControl->id; + + $this->json('POST', route('api.projects.servers.sites.create', [ + 'project' => $this->server->project, + 'server' => $this->server, + ]), $inputs) + ->assertSuccessful() + ->assertJsonFragment([ + 'domain' => $inputs['domain'], + 'aliases' => $inputs['aliases'] ?? [], + ]); + } + + public function test_see_sites_list(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var Site $site */ + $site = Site::factory()->create([ + 'server_id' => $this->server->id, + ]); + + $this->json('GET', route('api.projects.servers.sites', [ + 'project' => $this->server->project, + 'server' => $this->server, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'domain' => $site->domain, + ]); + } + + public function test_delete_site(): void + { + SSH::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var Site $site */ + $site = Site::factory()->create([ + 'server_id' => $this->server->id, + ]); + + $this->json('DELETE', route('api.projects.servers.sites.delete', [ + 'project' => $this->server->project, + 'server' => $this->server, + 'site' => $site, + ])) + ->assertSuccessful() + ->assertNoContent(); + } + + public static function create_data(): array + { + return \Tests\Feature\SitesTest::create_data(); + } +} diff --git a/tests/Feature/API/SourceControlsTest.php b/tests/Feature/API/SourceControlsTest.php new file mode 100644 index 0000000..f269151 --- /dev/null +++ b/tests/Feature/API/SourceControlsTest.php @@ -0,0 +1,134 @@ +user, ['read', 'write']); + + Http::fake(); + + $input = array_merge([ + 'name' => 'test', + 'provider' => $provider, + ], $input); + + $this->json('POST', route('api.projects.source-controls.create', [ + 'project' => $this->user->current_project_id, + ]), $input) + ->assertSuccessful() + ->assertJsonFragment([ + 'provider' => $provider, + 'name' => 'test', + ]); + } + + /** + * @dataProvider data + */ + public function test_delete_provider(string $provider): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var SourceControl $sourceControl */ + $sourceControl = SourceControl::factory()->create([ + 'provider' => $provider, + 'profile' => 'test', + ]); + + $this->json('DELETE', route('api.projects.source-controls.delete', [ + 'project' => $this->user->current_project_id, + 'sourceControl' => $sourceControl->id, + ])) + ->assertSuccessful() + ->assertNoContent(); + } + + /** + * @dataProvider data + */ + public function test_cannot_delete_provider(string $provider): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var SourceControl $sourceControl */ + $sourceControl = SourceControl::factory()->create([ + 'provider' => $provider, + 'profile' => 'test', + ]); + + $this->site->update([ + 'source_control_id' => $sourceControl->id, + ]); + + Livewire::test(SourceControlsList::class) + ->callTableAction('delete', $sourceControl->id) + ->assertNotified('This source control is being used by a site.'); + + $this->assertNotSoftDeleted('source_controls', [ + 'id' => $sourceControl->id, + ]); + } + + /** + * @dataProvider data + */ + public function test_edit_source_control(string $provider, array $input): void + { + Http::fake(); + + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var SourceControl $sourceControl */ + $sourceControl = SourceControl::factory()->create([ + 'provider' => $provider, + 'profile' => 'old-name', + 'url' => $input['url'] ?? null, + ]); + + $this->json('PUT', route('api.projects.source-controls.update', [ + 'project' => $this->user->current_project_id, + 'sourceControl' => $sourceControl->id, + ]), array_merge([ + 'name' => 'new-name', + ], $input)) + ->assertSuccessful() + ->assertJsonFragment([ + 'provider' => $provider, + 'name' => 'new-name', + ]); + + $sourceControl->refresh(); + + $this->assertEquals('new-name', $sourceControl->profile); + if (isset($input['url'])) { + $this->assertEquals($input['url'], $sourceControl->url); + } + } + + public static function data(): array + { + return [ + ['github', ['token' => 'test']], + ['github', ['token' => 'test', 'global' => '1']], + ['gitlab', ['token' => 'test']], + ['gitlab', ['token' => 'test', 'url' => 'https://git.example.com/']], + ['bitbucket', ['username' => 'test', 'password' => 'test']], + ]; + } +} diff --git a/tests/Feature/API/StorageProvidersTest.php b/tests/Feature/API/StorageProvidersTest.php new file mode 100644 index 0000000..fb28232 --- /dev/null +++ b/tests/Feature/API/StorageProvidersTest.php @@ -0,0 +1,173 @@ +user, ['read', 'write']); + + if ($input['provider'] === StorageProvider::DROPBOX) { + Http::fake(); + } + + if ($input['provider'] === StorageProvider::FTP) { + FTP::fake(); + } + + $this->json('POST', route('api.projects.storage-providers.create', [ + 'project' => $this->user->current_project_id, + ]), $input) + ->assertSuccessful() + ->assertJsonFragment([ + 'provider' => $input['provider'], + 'name' => $input['name'], + ]); + } + + public function test_see_providers_list(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var StorageProviderModel $provider */ + $provider = StorageProviderModel::factory()->create([ + 'user_id' => $this->user->id, + 'provider' => StorageProvider::DROPBOX, + ]); + + $this->json('GET', route('api.projects.storage-providers', [ + 'project' => $this->user->current_project_id, + ])) + ->assertSuccessful() + ->assertJsonFragment([ + 'provider' => $provider->provider, + 'name' => $provider->profile, + ]); + } + + public function test_delete_provider(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var StorageProviderModel $provider */ + $provider = StorageProviderModel::factory()->create([ + 'user_id' => $this->user->id, + ]); + + $this->json('DELETE', route('api.projects.storage-providers.delete', [ + 'project' => $this->user->current_project_id, + 'storageProvider' => $provider->id, + ])) + ->assertSuccessful() + ->assertNoContent(); + } + + public function test_cannot_delete_provider(): void + { + Sanctum::actingAs($this->user, ['read', 'write']); + + /** @var Database $database */ + $database = Database::factory()->create([ + 'server_id' => $this->server, + ]); + + /** @var StorageProviderModel $provider */ + $provider = StorageProviderModel::factory()->create([ + 'user_id' => $this->user->id, + ]); + + Backup::factory()->create([ + 'server_id' => $this->server->id, + 'database_id' => $database->id, + 'storage_id' => $provider->id, + ]); + + $this->json('DELETE', route('api.projects.storage-providers.delete', [ + 'project' => $this->user->current_project_id, + 'storageProvider' => $provider->id, + ])) + ->assertJsonValidationErrorFor('provider'); + } + + /** + * @TODO: complete FTP tests + */ + public static function createData(): array + { + return [ + [ + [ + 'provider' => StorageProvider::LOCAL, + 'name' => 'local-test', + 'path' => '/home/vito/backups', + ], + ], + [ + [ + 'provider' => StorageProvider::LOCAL, + 'name' => 'local-test', + 'path' => '/home/vito/backups', + 'global' => 1, + ], + ], + [ + [ + 'provider' => StorageProvider::FTP, + 'name' => 'ftp-test', + 'host' => '1.2.3.4', + 'port' => '22', + 'path' => '/home/vito', + 'username' => 'username', + 'password' => 'password', + 'ssl' => 1, + 'passive' => 1, + ], + ], + [ + [ + 'provider' => StorageProvider::FTP, + 'name' => 'ftp-test', + 'host' => '1.2.3.4', + 'port' => '22', + 'path' => '/home/vito', + 'username' => 'username', + 'password' => 'password', + 'ssl' => 1, + 'passive' => 1, + 'global' => 1, + ], + ], + [ + [ + 'provider' => StorageProvider::DROPBOX, + 'name' => 'dropbox-test', + 'token' => 'token', + ], + ], + [ + [ + 'provider' => StorageProvider::DROPBOX, + 'name' => 'dropbox-test', + 'token' => 'token', + 'global' => 1, + ], + ], + ]; + } +} diff --git a/tests/Feature/ServicesTest.php b/tests/Feature/ServicesTest.php index c7efe4f..0cc55f8 100644 --- a/tests/Feature/ServicesTest.php +++ b/tests/Feature/ServicesTest.php @@ -302,12 +302,6 @@ public static function data(): array { return [ ['nginx'], - ['php'], - ['supervisor'], - ['redis'], - ['ufw'], - ['php'], - ['mysql'], ]; }