private void requireRemovable(Node node, boolean removingRecursively, boolean force) {
        if (force) return;

        if (node.type() == NodeType.tenant && node.allocation().isPresent()) {
            EnumSet<Node.State> removableStates = EnumSet.of(Node.State.failed, Node.State.parked);
            if (!removingRecursively || !removableStates.contains(node.state()))
                illegal(node + " is currently allocated and cannot be removed while in " + node.state());
        }

        final Set<Node.State> removableStates;
        if (node.type().isHost()) {
            removableStates = EnumSet.of(Node.State.provisioned, Node.State.failed, Node.State.parked);
        } else {
            removableStates = removingRecursively
                    ? EnumSet.of(Node.State.provisioned, Node.State.failed, Node.State.parked, Node.State.dirty, Node.State.ready)
                    // When not removing recursively, we can only remove children in state ready
                    : EnumSet.of(Node.State.ready);
        }
        if (!removableStates.contains(node.state()))
            illegal(node + " can not be removed while in " + node.state());
    }
Throws if the given node cannot be removed. Removal is allowed if:
 - Tenant node:
   - non-recursively: node is unallocated
   - recursively: node is unallocated or node is in failed|parked
 - Host node: iff in state provisioned|failed|parked
 - Child node:
   - non-recursively: node in state ready
   - recursively: child is in state provisioned|failed|parked|dirty|ready
node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java