public Result evaluateTransition(Node node, ClusterState clusterState, SetUnitStateRequest.Condition condition,
                                     NodeState oldWantedState, NodeState newWantedState) {
        if (condition == FORCE)
            return allow();

        if (inMoratorium)
            return disallow("Master cluster controller is bootstrapping and in moratorium");

        if (condition != SAFE)
            return disallow("Condition not implemented: " + condition.name());

        if (node.getType() != STORAGE)
            return disallow("Safe-set of node state is only supported for storage nodes! " +
                            "Requested node type: " + node.getType().toString());

        StorageNodeInfo nodeInfo = clusterInfo.getStorageNodeInfo(node.getIndex());
        if (nodeInfo == null)
            return disallow("Unknown node " + node);

        if (noChanges(oldWantedState, newWantedState))
            return alreadySet();

        return switch (newWantedState.getState()) {
            case UP -> canSetStateUp(nodeInfo, oldWantedState);
            case MAINTENANCE -> canSetStateMaintenanceTemporarily(nodeInfo, clusterState, newWantedState.getDescription());
            case DOWN -> canSetStateDownPermanently(nodeInfo, clusterState, newWantedState.getDescription());
            default -> disallow("Destination node state unsupported in safe mode: " + newWantedState);
        };
    }
Checks if a node can be upgraded.

@author Haakon Dybdahl
clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/NodeStateChangeChecker.java