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

Handle wildcard parameter in Quota deletion API #465

Merged
merged 2 commits into from
Oct 9, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class ResourceQuotaController extends NamespacedResourceController {
* List quotas by namespace.
*
* @param namespace The namespace
* @param name The name parameter
* @return A list of quotas
*/
@Get
Expand All @@ -59,7 +60,7 @@ public List<ResourceQuotaResponse> list(String namespace, @QueryValue(defaultVal
* @param namespace The name
* @param quota The quota name
* @return A quota
* @deprecated use list(String, String name) instead.
* @deprecated use {@link #list(String, String)} instead.
*/
@Get("/{quota}")
@Deprecated(since = "1.12.0")
Expand Down Expand Up @@ -115,16 +116,55 @@ public HttpResponse<ResourceQuota> apply(String namespace, @Body @Valid Resource
return formatHttpResponse(resourceQuotaService.create(quota), status);
}

/**
* Delete quotas.
*
* @param namespace The namespace
* @param name The name parameter
* @param dryrun Is dry run mode or not?
* @return An HTTP response
*/
@Delete
@Status(HttpStatus.NO_CONTENT)
public HttpResponse<Void> bulkDelete(String namespace, @QueryValue(defaultValue = "*") String name,
@QueryValue(defaultValue = "false") boolean dryrun) {

List<ResourceQuota> resourceQuotas = resourceQuotaService.findByWildcardName(namespace, name);

if (resourceQuotas.isEmpty()) {
return HttpResponse.notFound();
}

if (dryrun) {
return HttpResponse.noContent();
}

resourceQuotas.forEach(resourceQuota -> {
sendEventLog(
resourceQuota,
ApplyStatus.deleted,
resourceQuota.getSpec(),
null,
EMPTY_STRING
);
resourceQuotaService.delete(resourceQuota);
});

return HttpResponse.noContent();
}

/**
* Delete a quota.
*
* @param namespace The namespace
* @param name The resource quota
* @param dryrun Is dry run mode or not ?
* @param dryrun Is dry run mode or not?
* @return An HTTP response
* @deprecated use {@link #bulkDelete(String, String, boolean)} instead.
*/
@Delete("/{name}{?dryrun}")
@Status(HttpStatus.NO_CONTENT)
@Deprecated(since = "1.13.0")
public HttpResponse<Void> delete(String namespace, String name,
@QueryValue(defaultValue = "false") boolean dryrun) {
Optional<ResourceQuota> resourceQuota = resourceQuotaService.findByName(namespace, name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,19 +321,21 @@ void shouldApplyUpdated() {
}

@Test
void shouldDeleteWhenNotFound() {
@SuppressWarnings("deprecation")
void shouldNotDeleteQuotaWhenNotFound() {
when(resourceQuotaService.findByName("test", "quota")).thenReturn(Optional.empty());
HttpResponse<Void> actual = resourceQuotaController.delete("test", "quota", false);
assertEquals(HttpStatus.NOT_FOUND, actual.getStatus());
verify(resourceQuotaService, never()).delete(ArgumentMatchers.any());
}

@Test
void shouldDeleteWhenDryRun() {
@SuppressWarnings("deprecation")
void shouldNotDeleteQuotaWhenDryRun() {
ResourceQuota resourceQuota = ResourceQuota.builder()
.metadata(Metadata.builder()
.cluster("local")
.name("created-quota")
.name("quota")
.build())
.spec(Map.of("count/topics", "3"))
.build();
Expand All @@ -345,11 +347,12 @@ void shouldDeleteWhenDryRun() {
}

@Test
void shouldDelete() {
@SuppressWarnings("deprecation")
void shouldDeleteQuota() {
ResourceQuota resourceQuota = ResourceQuota.builder()
.metadata(Metadata.builder()
.cluster("local")
.name("created-quota")
.name("quota")
.build())
.spec(Map.of("count/topics", "3"))
.build();
Expand All @@ -364,4 +367,49 @@ void shouldDelete() {
assertEquals(HttpStatus.NO_CONTENT, actual.getStatus());
verify(resourceQuotaService).delete(resourceQuota);
}

@Test
void shouldNotBulkDeleteQuotaWhenNotFound() {
when(resourceQuotaService.findByWildcardName("test", "quota*")).thenReturn(List.of());
HttpResponse<Void> actual = resourceQuotaController.bulkDelete("test", "quota*", false);
assertEquals(HttpStatus.NOT_FOUND, actual.getStatus());
verify(resourceQuotaService, never()).delete(ArgumentMatchers.any());
}

@Test
void shouldNotBulkDeleteQuotaWhenDryRun() {
ResourceQuota resourceQuota1 = ResourceQuota.builder()
.metadata(Metadata.builder()
.cluster("local")
.name("quota1")
.build())
.spec(Map.of("count/topics", "3"))
.build();

when(resourceQuotaService.findByWildcardName("test", "quota*")).thenReturn(List.of(resourceQuota1));
HttpResponse<Void> actual = resourceQuotaController.bulkDelete("test", "quota*", true);
assertEquals(HttpStatus.NO_CONTENT, actual.getStatus());
verify(resourceQuotaService, never()).delete(ArgumentMatchers.any());
}

@Test
void shouldBulkDeleteQuota() {
ResourceQuota resourceQuota = ResourceQuota.builder()
.metadata(Metadata.builder()
.cluster("local")
.name("quota")
.build())
.spec(Map.of("count/topics", "3"))
.build();

when(resourceQuotaService.findByWildcardName("test", "quota*")).thenReturn(List.of(resourceQuota));
when(securityService.username()).thenReturn(Optional.of("test-user"));
when(securityService.hasRole(ResourceBasedSecurityRule.IS_ADMIN)).thenReturn(false);
doNothing().when(applicationEventPublisher).publishEvent(any());
doNothing().when(resourceQuotaService).delete(resourceQuota);

HttpResponse<Void> actual = resourceQuotaController.bulkDelete("test", "quota*", false);
assertEquals(HttpStatus.NO_CONTENT, actual.getStatus());
verify(resourceQuotaService).delete(resourceQuota);
}
}