private HttpResponse handlePUT(HttpRequest request) {
        Path path = new Path(request.getUri());
        // Check paths to disallow illegal state changes
        if (path.matches("/nodes/v2/state/ready/{hostname}")) {
            if (nodeRepository.nodes().markNodeAvailableForNewAllocation(path.get("hostname"), agent(request), "Readied through the nodes/v2 API"))
                infraApplicationRedeployer.readied(nodeRepository.nodes().node(path.get("hostname")).get().type());
            return new MessageResponse("Moved " + path.get("hostname") + " to " + Node.State.ready);
        }
        else if (path.matches("/nodes/v2/state/failed/{hostname}")) {
            var failedOrMarkedNodes = NodeList.copyOf(nodeRepository.nodes().failOrMarkRecursively(path.get("hostname"), agent(request), "Failed through the nodes/v2 API"));
            return new MessageResponse("Moved " + hostnamesAsString(failedOrMarkedNodes.state(Node.State.failed).asList()) + " to " + Node.State.failed +
                                       " and marked " + hostnamesAsString(failedOrMarkedNodes.failing().asList()) + " as wantToFail");
        }
        else if (path.matches("/nodes/v2/state/parked/{hostname}")) {
            List<Node> parkedNodes = nodeRepository.nodes().parkRecursively(path.get("hostname"), agent(request), false, "Parked through the nodes/v2 API");
            return new MessageResponse("Moved " + hostnamesAsString(parkedNodes) + " to " + Node.State.parked);
        }
        else if (path.matches("/nodes/v2/state/dirty/{hostname}")) {
            List<Node> dirtiedNodes = nodeRepository.nodes().deallocateRecursively(path.get("hostname"), agent(request), "Dirtied through the nodes/v2 API");
            return new MessageResponse("Moved " + hostnamesAsString(dirtiedNodes) + " to " + Node.State.dirty);
        }
        else if (path.matches("/nodes/v2/state/active/{hostname}")) {
            nodeRepository.nodes().reactivate(path.get("hostname"), agent(request), "Reactivated through nodes/v2 API");
            return new MessageResponse("Moved " + path.get("hostname") + " to " + Node.State.active);
        }
        else if (path.matches("/nodes/v2/state/breakfixed/{hostname}")) {
            List<Node> breakfixedNodes = nodeRepository.nodes().breakfixRecursively(path.get("hostname"), agent(request), "Breakfixed through the nodes/v2 API");
            return new MessageResponse("Moved " + hostnamesAsString(breakfixedNodes) + " to " + Node.State.breakfixed);
        }

        throw new NotFoundException("Cannot put to path '" + path + "'");
    }
The implementation of the /nodes/v2 API.
See NodesV2ApiTest for documentation.

@author bratseth
node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java