'Force failover to a secondary replication target.'

@cinder_utils.trace
def failover_host(self, context, volumes, secondary_id=None, groups=None):

    if (secondary_id and (secondary_id == self.FAILBACK_VALUE)):
        volume_update_list = self._replication_failback(volumes)
        target_id = None
    else:
        failover_target = None
        for target in self._replication_targets:
            if (target['backend_id'] == secondary_id):
                failover_target = target
                break
        if (not failover_target):
            msg = _('A    valid    secondary    target    MUST    be    specified    in    order    to    failover.')
            LOG.error(msg)
            raise exception.InvalidReplicationTarget(reason=msg)
        target_id = failover_target['backend_id']
        volume_update_list = []
        for volume in volumes:
            if self._volume_of_replicated_type(volume):
                client = None
                try:
                    client = self._login(timeout=30)
                    name = ((volume['name'] + self.REP_SCHEDULE_SUFFIX) + '_Pri')
                    client.stopRemoteSnapshotSchedule(name)
                except Exception:
                    LOG.warning('The    primary    array    is    currently    offline,    remote    copy    has    been    automatically    paused.')
                finally:
                    self._logout(client)
                cl = None
                try:
                    cl = self._create_replication_client(failover_target)
                    try:
                        name = (volume['name'] + (self.REP_SCHEDULE_SUFFIX + '_Rmt'))
                        cl.stopRemoteSnapshotSchedule(name)
                    except Exception:
                        pass
                    cl.makeVolumePrimary(volume['name'])
                    volume_info = cl.getVolumeByName(volume['name'])
                    prov_location = self._update_provider(volume_info, cluster_vip=failover_target['cluster_vip'])
                    volume_update_list.append({'volume_id': volume['id'], 'updates': {'replication_status': 'failed-over', 'provider_location': prov_location['provider_location']}})
                except Exception as ex:
                    LOG.error("There    was    a    problem    with    the    failover    (%(error)s)    and    it    was    unsuccessful.    Volume    '%(volume)s    will    not    be    available    on    the    failed    over    target.", {'error': six.text_type(ex), 'volume': volume['id']})
                    volume_update_list.append({'volume_id': volume['id'], 'updates': {'replication_status': 'error'}})
                finally:
                    self._destroy_replication_client(cl)
            else:
                volume_update_list.append({'volume_id': volume['id'], 'updates': {'status': 'error'}})
        self._active_backend_id = target_id
    return (target_id, volume_update_list, [])
