Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(server): implement bucket update & deletion apis #447

Merged
merged 1 commit into from
Nov 29, 2022
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
feat(server): implement bucket update & deletion apis
Signed-off-by: maslow <wangfugen@126.com>
  • Loading branch information
maslow committed Nov 29, 2022
commit 71e54359f47553d15c4ea94d0151e6d8b7a84bb5
2 changes: 1 addition & 1 deletion server/src/applications/applications.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export class ApplicationsService {
const res = await this.k8sClient.deleteCustomObject(app)
return res
} catch (error) {
this.logger.error(error)
this.logger.error(error, error.response?.body)
return null
}
}
Expand Down
62 changes: 51 additions & 11 deletions server/src/buckets/buckets.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,64 @@ export class BucketsController {
@ApiOperation({ summary: 'Get a bucket by name' })
@UseGuards(JwtAuthGuard, ApplicationAuthGuard)
@Get(':name')
findOne(@Param('appid') appid: string, @Param('name') name: string) {
const data = this.bucketsService.findOne(appid, name)
async findOne(@Param('appid') appid: string, @Param('name') name: string) {
const data = await this.bucketsService.findOne(appid, name)
if (null === data) {
throw new HttpException('bucket not found', HttpStatus.NOT_FOUND)
}

return ResponseUtil.ok(data)
}

@ApiOperation({ summary: 'TODO - ⌛️' })
@Patch(':id')
update(@Param('id') id: string, @Body() updateBucketDto: UpdateBucketDto) {
return this.bucketsService.update(+id, updateBucketDto)
/**
* Update a bucket
* @param appid
* @param name bucket name
* @param dto
* @returns
*/
@ApiOperation({ summary: 'Update a bucket' })
@ApiResponseUtil(Bucket)
@UseGuards(JwtAuthGuard, ApplicationAuthGuard)
@Patch(':name')
async update(
@Param('appid') appid: string,
@Param('name') name: string,
@Body() dto: UpdateBucketDto,
) {
const bucket = await this.bucketsService.findOne(appid, name)
if (!bucket) {
throw new HttpException('bucket not found', HttpStatus.NOT_FOUND)
}

// TODO check the storage capacity of the app

const res = await this.bucketsService.update(bucket, dto)
if (null === res) {
return ResponseUtil.error('update bucket failed')
}
return ResponseUtil.ok(res)
}

@ApiOperation({ summary: 'TODO - ⌛️' })
@Delete(':id')
remove(@Param('id') id: string) {
return this.bucketsService.remove(+id)
/**
* Delete a bucket
* @param appid
* @param name bucket name
* @returns
*/
@ApiResponseUtil(Bucket)
@UseGuards(JwtAuthGuard, ApplicationAuthGuard)
@ApiOperation({ summary: 'Delete a bucket' })
@Delete(':name')
async remove(@Param('appid') appid: string, @Param('name') name: string) {
const bucket = await this.bucketsService.findOne(appid, name)
if (!bucket) {
throw new HttpException('bucket not found', HttpStatus.NOT_FOUND)
}

const res = await this.bucketsService.remove(bucket)
if (null === res) {
return ResponseUtil.error('delete bucket failed')
}
return ResponseUtil.ok(res)
}
}
42 changes: 34 additions & 8 deletions server/src/buckets/buckets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export class BucketsService {
logger: Logger = new Logger(BucketsService.name)
constructor(private readonly k8sClient: KubernetesService) {}

/**
* Create a new bucket
* @param appid
* @param dto
* @returns
*/
async create(appid: string, dto: CreateBucketDto) {
const namespace = GetApplicationNamespaceById(appid)
const bucket = new Bucket(dto.fullname(appid), namespace)
Expand All @@ -20,7 +26,7 @@ export class BucketsService {

try {
const res = await this.k8sClient.objectApi.create(bucket)
return res.body
return Bucket.fromObject(res.body)
} catch (error) {
this.logger.error(error)
return null
Expand All @@ -46,7 +52,7 @@ export class BucketsService {
labelSelector,
)

return res.body as BucketList
return BucketList.fromObject(res.body as any)
}

async findOne(appid: string, name: string): Promise<Bucket> {
Expand All @@ -60,21 +66,41 @@ export class BucketsService {
Bucket.GVK.plural,
name,
)
return res.body as Bucket
return Bucket.fromObject(res.body)
} catch (err) {
this.logger.error(err)
if (err?.response?.body?.reason === 'NotFound') {
return null
}
this.logger.error(err, err.response?.body)
throw err
}
}

update(id: number, updateBucketDto: UpdateBucketDto) {
return `This action updates a #${id} bucket`
async update(bucket: Bucket, dto: UpdateBucketDto) {
if (dto.policy) {
bucket.spec.policy = dto.policy
}

if (dto.storage) {
bucket.spec.storage = dto.storage
}

try {
const res = await this.k8sClient.patchCustomObject(bucket)
return Bucket.fromObject(res)
} catch (error) {
this.logger.error(error, error.response?.body)
return null
}
}

remove(id: number) {
return `This action removes a #${id} bucket`
async remove(bucket: Bucket) {
try {
const res = await this.k8sClient.deleteCustomObject(bucket)
return Bucket.fromObject(res)
} catch (error) {
this.logger.error(error, error.response?.body)
return null
}
}
}
18 changes: 15 additions & 3 deletions server/src/buckets/dto/update-bucket.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import { PartialType } from '@nestjs/mapped-types'
import { CreateBucketDto } from './create-bucket.dto'
import { ApiProperty } from '@nestjs/swagger'
import { IsEnum, IsNotEmpty, IsString } from 'class-validator'
import { BucketPolicy } from '../entities/bucket.entity'

export class UpdateBucketDto extends PartialType(CreateBucketDto) {}
export class UpdateBucketDto {
@ApiProperty({ enum: BucketPolicy })
@IsEnum(BucketPolicy)
policy: BucketPolicy

@ApiProperty({
description: 'The storage capacity of the bucket: "1Gi", "0.5Gi", "100Gi"',
})
@IsNotEmpty()
@IsString()
storage: string
}
16 changes: 15 additions & 1 deletion server/src/buckets/entities/bucket.entity.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KubernetesObject } from '@kubernetes/client-node'
import { KubernetesListObject, KubernetesObject } from '@kubernetes/client-node'
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
import {
Condition,
Expand Down Expand Up @@ -85,6 +85,13 @@ export class Bucket implements KubernetesObject {
this.metadata = new ObjectMeta(name, namespace)
this.spec = new BucketSpec()
}

static fromObject(obj: KubernetesObject): Bucket {
const bucket = new Bucket(obj.metadata.name, obj.metadata.namespace)
delete obj.metadata['managedFields']
Object.assign(bucket, obj)
return bucket
}
}

export class BucketList {
Expand All @@ -95,4 +102,11 @@ export class BucketList {
type: [Bucket],
})
items: Bucket[]

static fromObject(obj: KubernetesListObject<Bucket>): BucketList {
const list = new BucketList()
Object.assign(list, obj)
list.items = obj.items.map((item) => Bucket.fromObject(item))
return list
}
}