From 84ea0fb35fd5ef438dc58f29ad4dacec37640e43 Mon Sep 17 00:00:00 2001 From: Michael Burman Date: Mon, 25 Nov 2024 15:19:14 +0200 Subject: [PATCH] Add new parameter to /start, consistency. Supports -Ddse.consistent_replace=X --- CHANGELOG.md | 2 ++ management-api-server/doc/openapi.json | 17 +++++++++++++ .../mgmtapi/ManagementApplication.java | 2 +- .../mgmtapi/resources/LifecycleResources.java | 24 +++++++++++++++++-- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67d82b4d..b00248ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ Changelog for Management API, new PRs should update the `main / unreleased` sect ## unreleased +* [ENHANCEMENT] [#574](https://github.com/k8ssandra/management-api-for-apache-cassandra/issues/574) Support consistency parameter in the /start when replacing a DSE node. + ## v0.1.90 (2024-11-22) * [FEATURE] [#566](https://github.com/k8ssandra/management-api-for-apache-cassandra/issues/566) Add listRoles and dropRole functionality to the REST interface * [FEATURE] [#571](https://github.com/k8ssandra/management-api-for-apache-cassandra/issues/571) Add Cassandra 4.0.15 to the build matrix diff --git a/management-api-server/doc/openapi.json b/management-api-server/doc/openapi.json index 39597558..f0b2f2eb 100644 --- a/management-api-server/doc/openapi.json +++ b/management-api-server/doc/openapi.json @@ -129,6 +129,12 @@ "schema" : { "type" : "string" } + }, { + "in" : "query", + "name" : "replace_consistency", + "schema" : { + "type" : "string" + } } ], "responses" : { "201" : { @@ -151,6 +157,17 @@ "206" : { "description" : "Cassandra process not found but can connect" }, + "400" : { + "content" : { + "text/plain" : { + "example" : "Invalid replace IP passed: 0.0.0.0.0", + "schema" : { + "type" : "string" + } + } + }, + "description" : "Invalid parameters" + }, "420" : { "content" : { "text/plain" : { diff --git a/management-api-server/src/main/java/com/datastax/mgmtapi/ManagementApplication.java b/management-api-server/src/main/java/com/datastax/mgmtapi/ManagementApplication.java index 2b8ac683..f2fbe1d2 100644 --- a/management-api-server/src/main/java/com/datastax/mgmtapi/ManagementApplication.java +++ b/management-api-server/src/main/java/com/datastax/mgmtapi/ManagementApplication.java @@ -83,7 +83,7 @@ public boolean checkState() { STATE currentState = getRequestedState(); logger.debug("Current Requested State is {}", currentState); if (currentState != STATE.STOPPED) { - Response r = lifecycle.startNode(getActiveProfile(), null); + Response r = lifecycle.startNode(getActiveProfile(), null, null); return r.getStatus() >= 200 && r.getStatus() < 300; } diff --git a/management-api-server/src/main/java/com/datastax/mgmtapi/resources/LifecycleResources.java b/management-api-server/src/main/java/com/datastax/mgmtapi/resources/LifecycleResources.java index 9b01a0cd..0bdfb3a0 100644 --- a/management-api-server/src/main/java/com/datastax/mgmtapi/resources/LifecycleResources.java +++ b/management-api-server/src/main/java/com/datastax/mgmtapi/resources/LifecycleResources.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.Uninterruptibles; import io.swagger.v3.oas.annotations.Hidden; @@ -90,6 +91,14 @@ public LifecycleResources(ManagementApplication app) { @ApiResponse(responseCode = "202", description = "Cassandra already running and can connect") @ApiResponse(responseCode = "204", description = "Cassandra already running but can't connect") @ApiResponse(responseCode = "206", description = "Cassandra process not found but can connect") + @ApiResponse( + responseCode = "400", + description = "Invalid parameters", + content = + @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema(implementation = String.class), + examples = @ExampleObject(value = "Invalid replace IP passed: 0.0.0.0.0"))) @ApiResponse( responseCode = "420", description = "Cassandra could not start successfully", @@ -107,7 +116,9 @@ public LifecycleResources(ManagementApplication app) { schema = @Schema(implementation = String.class), examples = @ExampleObject(value = "error message"))) public synchronized Response startNode( - @QueryParam("profile") String profile, @QueryParam("replace_ip") String replaceIp) { + @QueryParam("profile") String profile, + @QueryParam("replace_ip") String replaceIp, + @QueryParam("replace_consistency") String consistency) { // Todo we should add a CALL getPid command and compare; boolean canConnect; @@ -153,11 +164,20 @@ public synchronized Response startNode( if (replaceIp != null) { if (!replaceIp.matches(IPV4_PATTERN)) - return Response.serverError() + return Response.status(HttpStatus.SC_BAD_REQUEST) .entity(Entity.text("Invalid replace IP passed: " + replaceIp)) .build(); cmdArgs.add(String.format("-Dcassandra.replace_address_first_boot=%s", replaceIp)); + if (!Strings.isNullOrEmpty(consistency)) { + if (app.dbExe.getAbsolutePath().endsWith("dse")) { + cmdArgs.add(String.format("-Ddse.consistent_replace=%s", consistency)); + } else { + return Response.status(HttpStatus.SC_BAD_REQUEST) + .entity(Entity.text("Consistency parameter for replace is only accepted with DSE")) + .build(); + } + } } // Delete stale file if it exists