'Add a device to the ring. This device dict should have a minimum of the
following keys:
id      unique integer identifier amongst devices. Defaults to the next
id if the \'id\' key is not provided in the dict
weight  a float of the relative weight of this device as compared to
others; this indicates how many partitions the builder will try
to assign to this device
region  integer indicating which region the device is in
zone    integer indicating which zone the device is in; a given
partition will not be assigned to multiple devices within the
same (region, zone) pair if there is any alternative
ip      the ip address of the device
port    the tcp port of the device
device  the device\'s name on disk (sdb1, for example)
meta    general use \'extra\' field; for example: the online date, the
hardware description
.. note::
This will not rebalance the ring immediately as you may want to
make multiple changes for a single rebalance.
:param dev: device dict
:returns: id of device (not used in the tree anymore, but unknown
users may depend on it)'

def add_dev(self, dev):

    if ('id' not in dev):
        dev['id'] = 0
        if self.devs:
            try:
                dev['id'] = self.devs.index(None)
            except ValueError:
                dev['id'] = len(self.devs)
    if ((dev['id'] < len(self.devs)) and (self.devs[dev['id']] is not None)):
        raise exceptions.DuplicateDeviceError(('Duplicate    device    id:    %d' % dev['id']))
    while (dev['id'] >= len(self.devs)):
        self.devs.append(None)
    required_keys = ('ip', 'port', 'weight')
    if any(((required not in dev) for required in required_keys)):
        raise ValueError(('%r    is    missing    at    least    one    the    required    key    %r' % (dev, required_keys)))
    dev['weight'] = float(dev['weight'])
    dev['parts'] = 0
    dev.setdefault('meta', '')
    self.devs[dev['id']] = dev
    self.devs_changed = True
    self.version += 1
    return dev['id']
