diff options
author | Ola Aunrønning <olaa@verizonmedia.com> | 2021-03-12 10:39:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-12 10:39:40 +0100 |
commit | 6cd2a39ccb1a62c10dfae5adf9eba40eddf2c2c6 (patch) | |
tree | 5dbddf60ad96bc0cb25eed1f533b71645aa7d4d4 | |
parent | 99253f5769759e7fc379bdd9e135addda01509f0 (diff) | |
parent | 1e2ea75d1dc83fab3d70fdc120ebed360833c991 (diff) |
Merge pull request #16902 from vespa-engine/smorgrav/assessment_api_handler
Smorgrav/assessment api handler
5 files changed, 172 insertions, 1 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java index 391dd59fd0b..72210ec26ed 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java @@ -38,7 +38,8 @@ enum PathGroup { "/routing/v1/", "/routing/v1/status/environment/{*}", "/routing/v1/inactive/environment/{*}", - "/state/v1/{*}"), + "/state/v1/{*}", + "/changemanagement/v1/{*}"), /** Paths used for creating and reading user resources. */ user(PathPrefix.api, diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandler.java new file mode 100644 index 00000000000..1dbeaf7c235 --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandler.java @@ -0,0 +1,90 @@ +package com.yahoo.vespa.hosted.controller.restapi.changemanagement; + +import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.container.jdisc.LoggingRequestHandler; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.Path; +import com.yahoo.restapi.SlimeJsonResponse; +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Slime; +import com.yahoo.vespa.hosted.controller.Controller; +import com.yahoo.vespa.hosted.controller.auditlog.AuditLoggingRequestHandler; +import com.yahoo.yolean.Exceptions; + +import java.util.logging.Level; + +public class ChangeManagementApiHandler extends AuditLoggingRequestHandler { + + private final Controller controller; + + public ChangeManagementApiHandler(LoggingRequestHandler.Context ctx, Controller controller) { + super(ctx, controller.auditLogger()); + this.controller = controller; + } + + @Override + public HttpResponse auditAndHandle(HttpRequest request) { + try { + switch (request.getMethod()) { + case POST: + return post(request); + default: + return ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is unsupported"); + } + } catch (IllegalArgumentException e) { + return ErrorResponse.badRequest(Exceptions.toMessageString(e)); + } catch (RuntimeException e) { + log.log(Level.WARNING, "Unexpected error handling '" + request.getUri() + "'", e); + return ErrorResponse.internalServerError(Exceptions.toMessageString(e)); + } + } + + private HttpResponse post(HttpRequest request) { + Path path = new Path(request.getUri()); + if (path.matches("/changemanagement/v1/assessment")) return new SlimeJsonResponse(assessment()); + return ErrorResponse.notFoundError("Nothing at " + path); + } + + private Slime assessment() { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + + // This is the main structure that might be part of something bigger later + Cursor assessment = root.setObject("assessment"); + + // Updated gives clue to if the assessement is old + assessment.setString("updated", "2021-03-12:12:12:12Z"); + + // Assessment on the cluster level + Cursor apps = assessment.setArray("clusters"); + Cursor oneCluster = apps.addObject(); + oneCluster.setString("app", "mytenant:myapp:myinstance"); + oneCluster.setString("zone", "prod.us-east-3"); + oneCluster.setString("cluster", "mycontent"); + oneCluster.setLong("clusterSize", 19); + oneCluster.setLong("clusterImpact", 3); + oneCluster.setString("upgradePolicy","10%"); + oneCluster.setDouble("utilizationInWindow", 0.5); + oneCluster.setString("suggestedAction", "nothing|bcp"); + oneCluster.setString("impact", "low|degraded|outage"); + + Cursor groups = oneCluster.setArray("groups"); + Cursor oneGroup = groups.addObject(); + oneGroup.setString("groupId", "23"); + oneGroup.setLong("groupSize", 4); + oneGroup.setLong("groupImpact", 2); + + // Assessment on the host level + Cursor hosts = assessment.setArray("hosts"); + Cursor oneHost = hosts.addObject(); + oneHost.setString("hostname", "myhostname"); + oneHost.setString("resources", "vcpu:memory:disk"); + oneHost.setString("state", "active"); + oneHost.setLong("containers", 10); + oneHost.setString("suggestedAction", "nothing|retire"); + oneHost.setString("impact", "low|degraded|outage"); //For hosts this is mostly decided by request + + return slime; + } +}
\ No newline at end of file diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java index 4b4a8415d69..50123e497dc 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java @@ -108,6 +108,9 @@ public class ControllerContainerTest { " <binding>http://*/routing/v1/*</binding>\n" + " <binding>http://*/api/routing/v1/*</binding>\n" + " </handler>\n" + + " <handler id='com.yahoo.vespa.hosted.controller.restapi.changemanagement.ChangeManagementApiHandler'>\n" + + " <binding>http://*/changemanagement/v1/*</binding>\n" + + " </handler>\n" + variablePartXml() + "</container>"; } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java new file mode 100644 index 00000000000..ff0b3b83383 --- /dev/null +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandlerTest.java @@ -0,0 +1,42 @@ +// Copyright 2021 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.restapi.changemanagement; + +import com.yahoo.application.container.handler.Request; +import com.yahoo.vespa.athenz.api.AthenzIdentity; +import com.yahoo.vespa.athenz.api.AthenzUser; +import com.yahoo.vespa.hosted.controller.restapi.ContainerTester; +import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest; +import org.intellij.lang.annotations.Language; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; + +public class ChangeManagementApiHandlerTest extends ControllerContainerTest { + + private static final String responses = "src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/responses/"; + private static final AthenzIdentity operator = AthenzUser.fromUserId("operatorUser"); + + private ContainerTester tester; + + @Before + public void before() { + tester = new ContainerTester(container, responses); + addUserToHostedOperatorRole(operator); + } + + @Test + public void test_api() { + assertFile(new Request("http://localhost:8080/changemanagement/v1/assessment", "{}", Request.Method.POST), "initial.json"); + } + + private void assertResponse(Request request, @Language("JSON") String body, int statusCode) { + addIdentityToRequest(request, operator); + tester.assertResponse(request, body, statusCode); + } + + private void assertFile(Request request, String filename) { + addIdentityToRequest(request, operator); + tester.assertResponse(request, new File(filename)); + } +} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/responses/initial.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/responses/initial.json new file mode 100644 index 00000000000..b402ff313dc --- /dev/null +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/responses/initial.json @@ -0,0 +1,35 @@ +{ + "assessment": { + "updated": "2021-03-12:12:12:12Z", + "clusters": [ + { + "app": "mytenant:myapp:myinstance", + "zone": "prod.us-east-3", + "cluster": "mycontent", + "clusterSize": 19, + "clusterImpact": 3, + "upgradePolicy": "10%", + "utilizationInWindow": 0.5, + "suggestedAction": "nothing|bcp", + "impact": "low|degraded|outage", + "groups": [ + { + "groupId": "23", + "groupSize": 4, + "groupImpact": 2 + } + ] + } + ], + "hosts": [ + { + "hostname": "myhostname", + "resources": "vcpu:memory:disk", + "state": "active", + "containers": 10, + "suggestedAction": "nothing|retire", + "impact": "low|degraded|outage" + } + ] + } +}
\ No newline at end of file |