feat: create/delete project endpoints

This commit is contained in:
Andras Bacsai 2024-07-23 11:36:05 +02:00
parent f134171855
commit 38299ab507
4 changed files with 259 additions and 3 deletions

View File

@ -135,8 +135,14 @@ public function environment_details(Request $request)
if (is_null($teamId)) { if (is_null($teamId)) {
return invalidTokenResponse(); return invalidTokenResponse();
} }
$project = Project::whereTeamId($teamId)->whereUuid(request()->uuid)->first(); if (! $request->uuid) {
$environment = $project->environments()->whereName(request()->environment_name)->first(); return response()->json(['message' => 'Uuid is required.'], 422);
}
if (! $request->environment_name) {
return response()->json(['message' => 'Environment name is required.'], 422);
}
$project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first();
$environment = $project->environments()->whereName($request->environment_name)->first();
if (! $environment) { if (! $environment) {
return response()->json(['message' => 'Environment not found.'], 404); return response()->json(['message' => 'Environment not found.'], 404);
} }
@ -144,4 +150,175 @@ public function environment_details(Request $request)
return response()->json(serializeApiResponse($environment)); return response()->json(serializeApiResponse($environment));
} }
#[OA\Post(
summary: 'Create Project',
description: 'Create Project.',
path: '/projects',
security: [
['bearerAuth' => []],
],
tags: ['Projects'],
requestBody: new OA\RequestBody(
required: true,
description: 'Project created.',
content: new OA\MediaType(
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
properties: [
'name' => ['type' => 'string', 'description' => 'The name of the project.'],
'description' => ['type' => 'string', 'description' => 'The description of the project.'],
],
),
),
),
responses: [
new OA\Response(
response: 201,
description: 'Project created.',
content: [
new OA\MediaType(
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
properties: [
'uuid' => ['type' => 'string', 'example' => 'og888os'],
'name' => ['type' => 'string', 'example' => 'Project Name'],
'description' => ['type' => 'string', 'example' => 'Project Description'],
]
)
),
]),
new OA\Response(
response: 401,
ref: '#/components/responses/401',
),
new OA\Response(
response: 400,
ref: '#/components/responses/400',
),
new OA\Response(
response: 404,
ref: '#/components/responses/404',
),
]
)]
public function create_project(Request $request)
{
$allowedFields = ['name', 'description'];
$teamId = getTeamIdFromToken();
if (is_null($teamId)) {
return invalidTokenResponse();
}
$return = validateIncomingRequest($request);
if ($return instanceof \Illuminate\Http\JsonResponse) {
return $return;
}
$validator = customApiValidator($request->all(), [
'name' => 'string|max:255',
'description' => 'string|nullable',
]);
$extraFields = array_diff(array_keys($request->all()), $allowedFields);
if ($validator->fails() || ! empty($extraFields)) {
$errors = $validator->errors();
if (! empty($extraFields)) {
foreach ($extraFields as $field) {
$errors->add($field, 'This field is not allowed.');
}
}
return response()->json([
'message' => 'Validation failed.',
'errors' => $errors,
], 422);
}
$project = Project::create([
'name' => $request->name,
'description' => $request->description,
'team_id' => $teamId,
]);
return response()->json([
'uuid' => $project->uuid,
'name' => $project->name,
'description' => $project->description,
])->status(201);
}
#[OA\Delete(
summary: 'Delete',
description: 'Delete project by UUID.',
path: '/projects/{uuid}',
security: [
['bearerAuth' => []],
],
tags: ['Projects'],
parameters: [
new OA\Parameter(
name: 'uuid',
in: 'path',
description: 'UUID of the application.',
required: true,
schema: new OA\Schema(
type: 'string',
format: 'uuid',
)
),
],
responses: [
new OA\Response(
response: 200,
description: 'Project deleted.',
content: [
new OA\MediaType(
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
properties: [
'message' => ['type' => 'string', 'example' => 'Project deleted.'],
]
)
),
]),
new OA\Response(
response: 401,
ref: '#/components/responses/401',
),
new OA\Response(
response: 400,
ref: '#/components/responses/400',
),
new OA\Response(
response: 404,
ref: '#/components/responses/404',
),
]
)]
public function delete_project(Request $request)
{
$teamId = getTeamIdFromToken();
if (is_null($teamId)) {
return invalidTokenResponse();
}
if (! $request->uuid) {
return response()->json(['message' => 'Uuid is required.'], 422);
}
$project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first();
if (! $project) {
return response()->json(['message' => 'Project not found.'], 404);
}
if ($project->resource_count() > 0) {
return response()->json(['message' => 'Project has resources, so it cannot be deleted.'], 400);
}
$project->delete();
return response()->json(['message' => 'Project deleted.']);
}
} }

View File

@ -122,7 +122,7 @@ public function mariadbs()
public function resource_count() public function resource_count()
{ {
return $this->applications()->count() + $this->postgresqls()->count() + $this->redis()->count() + $this->mongodbs()->count() + $this->mysqls()->count() + $this->mariadbs()->count() + $this->keydbs()->count() + $this->dragonflies()->count() + $this->services()->count() + $this->clickhouses()->count(); return $this->applications()->count() + $this->postgresqls()->count() + $this->redis()->count() + $this->mongodbs()->count() + $this->mysqls()->count() + $this->mariadbs()->count() + $this->keydbs()->count() + $this->dragonflies()->count() + $this->clickhouses()->count() + $this->services()->count();
} }
public function databases() public function databases()

View File

@ -3010,6 +3010,46 @@ paths:
security: security:
- -
bearerAuth: [] bearerAuth: []
post:
tags:
- Projects
summary: 'Create Project'
description: 'Create Project.'
operationId: cf067eb7cf18216cda3239329a2eeadb
requestBody:
description: 'Project created.'
required: true
content:
application/json:
schema:
properties:
name:
type: string
description: 'The name of the project.'
description:
type: string
description: 'The description of the project.'
type: object
responses:
'201':
description: 'Project created.'
content:
application/json:
schema:
properties:
uuid: { type: string, example: og888os }
name: { type: string, example: 'Project Name' }
description: { type: string, example: 'Project Description' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
'/projects/{uuid}': '/projects/{uuid}':
get: get:
tags: tags:
@ -3041,6 +3081,39 @@ paths:
security: security:
- -
bearerAuth: [] bearerAuth: []
delete:
tags:
- Projects
summary: Delete
description: 'Delete project by UUID.'
operationId: f668a936f505b4401948c74b6a663029
parameters:
-
name: uuid
in: path
description: 'UUID of the application.'
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 'Project deleted.'
content:
application/json:
schema:
properties:
message: { type: string, example: 'Project deleted.' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
'/projects/{uuid}/{environment_name}': '/projects/{uuid}/{environment_name}':
get: get:
tags: tags:
@ -4480,6 +4553,9 @@ components:
is_container_label_escape_enabled: is_container_label_escape_enabled:
type: boolean type: boolean
description: 'The flag to enable the container label escape.' description: 'The flag to enable the container label escape.'
is_container_label_readonly_enabled:
type: boolean
description: 'The flag to enable the container label readonly.'
config_hash: config_hash:
type: string type: string
description: 'The hash of the service configuration.' description: 'The hash of the service configuration.'

View File

@ -41,6 +41,9 @@
Route::get('/projects/{uuid}', [ProjectController::class, 'project_by_uuid']); Route::get('/projects/{uuid}', [ProjectController::class, 'project_by_uuid']);
Route::get('/projects/{uuid}/{environment_name}', [ProjectController::class, 'environment_details']); Route::get('/projects/{uuid}/{environment_name}', [ProjectController::class, 'environment_details']);
Route::post('/projects', [ProjectController::class, 'create_project']);
Route::delete('/projects/{uuid}', [ProjectController::class, 'delete_project']);
Route::get('/security/keys', [SecurityController::class, 'keys']); Route::get('/security/keys', [SecurityController::class, 'keys']);
Route::post('/security/keys', [SecurityController::class, 'create_key'])->middleware([IgnoreReadOnlyApiToken::class]); Route::post('/security/keys', [SecurityController::class, 'create_key'])->middleware([IgnoreReadOnlyApiToken::class]);