Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion redisinsight/api/src/modules/database/database.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { ApiTags } from '@nestjs/swagger';
import {
Body,
ClassSerializerInterceptor, Controller, Delete, Get, Param, Post, Put, UseInterceptors, UsePipes, ValidationPipe,
ClassSerializerInterceptor,
Controller,
Delete,
Get,
Param,
Patch,
Post,
Put,
UseInterceptors,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { ApiEndpoint } from 'src/decorators/api-endpoint.decorator';
import { Database } from 'src/modules/database/models/database';
Expand All @@ -16,6 +26,7 @@ import { DeleteDatabasesDto } from 'src/modules/database/dto/delete.databases.dt
import { DeleteDatabasesResponse } from 'src/modules/database/dto/delete.databases.response';
import { ClientMetadataParam } from 'src/common/decorators';
import { ClientMetadata } from 'src/common/models';
import { ModifyDatabaseDto } from 'src/modules/database/dto/modify.database.dto';

@ApiTags('Database')
@Controller('databases')
Expand Down Expand Up @@ -117,6 +128,34 @@ export class DatabaseController {
return await this.service.update(id, database, true);
}

@UseInterceptors(ClassSerializerInterceptor)
@UseInterceptors(new TimeoutInterceptor(ERROR_MESSAGES.CONNECTION_TIMEOUT))
@Patch(':id')
@ApiEndpoint({
description: 'Update database instance by id',
statusCode: 200,
responses: [
{
status: 200,
description: 'Updated database instance\' response',
type: Database,
},
],
})
@UsePipes(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
}),
)
async modify(
@Param('id') id: string,
@Body() database: ModifyDatabaseDto,
): Promise<Database> {
return await this.service.update(id, database, true);
}

@Delete('/:id')
@ApiEndpoint({
statusCode: 200,
Expand Down
3 changes: 2 additions & 1 deletion redisinsight/api/src/modules/database/database.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AppRedisInstanceEvents } from 'src/constants';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { DeleteDatabasesResponse } from 'src/modules/database/dto/delete.databases.response';
import { ClientContext } from 'src/common/models';
import { ModifyDatabaseDto } from 'src/modules/database/dto/modify.database.dto';

@Injectable()
export class DatabaseService {
Expand Down Expand Up @@ -118,7 +119,7 @@ export class DatabaseService {
// todo: remove manualUpdate flag logic
public async update(
id: string,
dto: UpdateDatabaseDto,
dto: UpdateDatabaseDto | ModifyDatabaseDto,
manualUpdate: boolean = true,
): Promise<Database> {
this.logger.log(`Updating database: ${id}`);
Expand Down
20 changes: 20 additions & 0 deletions redisinsight/api/src/modules/database/dto/modify.database.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { CreateDatabaseDto } from 'src/modules/database/dto/create.database.dto';
import { PartialType } from '@nestjs/swagger';
import {
IsInt, IsString, MaxLength, ValidateIf,
} from 'class-validator';

export class ModifyDatabaseDto extends PartialType(CreateDatabaseDto) {
@ValidateIf((object, value) => value !== undefined)
@IsString({ always: true })
@MaxLength(500)
name: string;

@ValidateIf((object, value) => value !== undefined)
@IsString({ always: true })
host: string;

@ValidateIf((object, value) => value !== undefined)
@IsInt({ always: true })
port: number;
}
96 changes: 92 additions & 4 deletions redisinsight/api/src/modules/database/dto/update.database.dto.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { CreateDatabaseDto } from 'src/modules/database/dto/create.database.dto';
import { PartialType } from '@nestjs/swagger';
import { ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger';
import {
IsInt, IsString, MaxLength, ValidateIf,
IsBoolean,
IsInt, IsNotEmpty, IsNotEmptyObject, IsOptional, IsString, MaxLength, Min, ValidateIf, ValidateNested,
} from 'class-validator';
import { CreateCaCertificateDto } from 'src/modules/certificate/dto/create.ca-certificate.dto';
import { UseCaCertificateDto } from 'src/modules/certificate/dto/use.ca-certificate.dto';
import { Expose, Type } from 'class-transformer';
import { caCertTransformer } from 'src/modules/certificate/transformers/ca-cert.transformer';
import { Default } from 'src/common/decorators';
import { CreateClientCertificateDto } from 'src/modules/certificate/dto/create.client-certificate.dto';
import { clientCertTransformer } from 'src/modules/certificate/transformers/client-cert.transformer';
import { UseClientCertificateDto } from 'src/modules/certificate/dto/use.client-certificate.dto';
import { SentinelMaster } from 'src/modules/redis-sentinel/models/sentinel-master';
import { CreateDatabaseDto } from 'src/modules/database/dto/create.database.dto';

export class UpdateDatabaseDto extends PartialType(CreateDatabaseDto) {
export class UpdateDatabaseDto extends CreateDatabaseDto {
@ValidateIf((object, value) => value !== undefined)
@IsString({ always: true })
@MaxLength(500)
Expand All @@ -17,4 +27,82 @@ export class UpdateDatabaseDto extends PartialType(CreateDatabaseDto) {
@ValidateIf((object, value) => value !== undefined)
@IsInt({ always: true })
port: number;

@ApiPropertyOptional({
description: 'Logical database number.',
type: Number,
})
@IsInt()
@Min(0)
@IsOptional()
@Default(null)
db?: number;

@ApiPropertyOptional({
description: 'Use TLS to connect.',
type: Boolean,
})
@IsBoolean()
@IsOptional()
@Default(false)
tls?: boolean;

@ApiPropertyOptional({
description: 'SNI servername',
type: String,
})
@IsString()
@IsNotEmpty()
@IsOptional()
@Default(null)
tlsServername?: string;

@ApiPropertyOptional({
description: 'The certificate returned by the server needs to be verified.',
type: Boolean,
default: false,
})
@IsOptional()
@IsBoolean({ always: true })
@Default(false)
verifyServerCert?: boolean;

@ApiPropertyOptional({
description: 'CA Certificate',
oneOf: [
{ $ref: getSchemaPath(CreateCaCertificateDto) },
{ $ref: getSchemaPath(UseCaCertificateDto) },
],
})
@IsOptional()
@IsNotEmptyObject()
@Type(caCertTransformer)
@ValidateNested()
@Default(null)
caCert?: CreateCaCertificateDto | UseCaCertificateDto;

@ApiPropertyOptional({
description: 'Client Certificate',
oneOf: [
{ $ref: getSchemaPath(CreateClientCertificateDto) },
{ $ref: getSchemaPath(UseCaCertificateDto) },
],
})
@IsOptional()
@IsNotEmptyObject()
@Type(clientCertTransformer)
@ValidateNested()
@Default(null)
clientCert?: CreateClientCertificateDto | UseClientCertificateDto;

@ApiPropertyOptional({
description: 'Redis OSS Sentinel master group.',
type: SentinelMaster,
})
@IsOptional()
@IsNotEmptyObject()
@Type(() => SentinelMaster)
@ValidateNested()
@Default(null)
sentinelMaster?: SentinelMaster;
}
Loading