code: func (c *cluster) diff(other *cluster) (action string, nodeID string, err error) {
  	lenFrom := len(c.nodes)
  	lenTo := len(other.nodes)
  	// Determine if a node is being added or removed.
  	if lenFrom == lenTo {
  		return "", "", errors.New("clusters are the same size")
  	}
  	if lenFrom < lenTo {
  		// Adding a node.
  		if lenTo-lenFrom > 1 {
  			return "", "", errors.New("adding more than one node at a time is not supported")
  		}
  		action = resizeJobActionAdd
  		// Determine the node ID that is being added.
  		for _, n := range other.nodes {
  			if c.unprotectedNodeByID(n.ID) == nil {
  				nodeID = n.ID
  				break
  			}
  		}
  	} else if lenFrom > lenTo {
  		// Removing a node.
  		if lenFrom-lenTo > 1 {
  			return "", "", errors.New("removing more than one node at a time is not supported")
  		}
  		action = resizeJobActionRemove
  		// Determine the node ID that is being removed.
  		for _, n := range c.nodes {
  			if other.unprotectedNodeByID(n.ID) == nil {
  				nodeID = n.ID
  				break
  			}
  		}
  	}
  	return action, nodeID, nil
  }
docs: // diff compares c with another cluster and determines if a node is being
  // added or removed. An error is returned for any case other than where
  // exactly one node is added or removed. unprotected.