'Failover to replication target.'

@kaminario_logger
def failover_host(self, context, volumes, secondary_id=None, groups=None):

    volume_updates = []
    back_end_ip = None
    svc_host = vol_utils.extract_host(self.host, 'backend')
    service = objects.Service.get_by_args(context, svc_host, 'cinder-volume')
    if (secondary_id and (secondary_id != self.replica.backend_id)):
        LOG.error('Kaminario    driver    received    failover_host    request,    But    backend    is    non    replicated    device')
        raise exception.UnableToFailOver(reason=_('Failover    requested    on    non    replicated    backend.'))
    if (service.active_backend_id and (service.active_backend_id != self.configuration.san_ip)):
        self.snap_updates = []
        rep_volumes = []
        for v in volumes:
            vol_name = self.get_volume_name(v['id'])
            vol = self.client.search('volumes', name=vol_name)
            if ((v.replication_status != K2_REP_FAILED_OVER) and vol.total):
                status = 'available'
                if v.volume_attachment:
                    map_rs = self.client.search('mappings', volume=vol.hits[0])
                    status = 'in-use'
                    if map_rs.total:
                        map_rs.hits[0].delete()
                volume_updates.append({'volume_id': v['id'], 'updates': {'status': status}})
            else:
                rep_volumes.append(v)
        for v in rep_volumes:
            vol_name = self.get_volume_name(v['id'])
            vol = self.client.search('volumes', name=vol_name)
            rvol_name = self.get_rep_name(vol_name)
            rvol = self.target.search('volumes', name=rvol_name)
            session_name = self.get_session_name(v['id'])
            rsession_name = self.get_rep_name(session_name)
            ssn = self.target.search('replication/sessions', name=rsession_name)
            if ssn.total:
                tgt_ssn = ssn.hits[0]
            ssn = self.client.search('replication/sessions', name=session_name)
            if ssn.total:
                src_ssn = ssn.hits[0]
            if ((tgt_ssn.state == 'failed_over') and (tgt_ssn.current_role == 'target') and vol.total and src_ssn):
                map_rs = self.client.search('mappings', volume=vol.hits[0])
                if map_rs.total:
                    map_rs.hits[0].delete()
                tgt_ssn.state = 'in_sync'
                tgt_ssn.save()
                self._check_for_status(src_ssn, 'in_sync')
            if (rvol.total and (src_ssn.state == 'in_sync') and (src_ssn.current_role == 'target')):
                gen_no = self._create_volume_replica_user_snap(self.target, tgt_ssn)
                self.snap_updates.append({'tgt_ssn': tgt_ssn, 'gno': gen_no, 'stime': time.time()})
            LOG.debug('The    target    session:    %s    state    is    changed    to    in    sync', rsession_name)
        self._is_user_snap_sync_finished()
        for v in rep_volumes:
            vol_name = self.get_volume_name(v['id'])
            vol = self.client.search('volumes', name=vol_name)
            rvol_name = self.get_rep_name(vol_name)
            rvol = self.target.search('volumes', name=rvol_name)
            session_name = self.get_session_name(v['id'])
            rsession_name = self.get_rep_name(session_name)
            ssn = self.target.search('replication/sessions', name=rsession_name)
            if ssn.total:
                tgt_ssn = ssn.hits[0]
            ssn = self.client.search('replication/sessions', name=session_name)
            if ssn.total:
                src_ssn = ssn.hits[0]
            if (rvol.total and (src_ssn.state == 'in_sync') and (src_ssn.current_role == 'target')):
                map_rs = self.target.search('mappings', volume=rvol.hits[0])
                if map_rs.total:
                    map_rs.hits[0].delete()
                gen_no = self._create_volume_replica_user_snap(self.target, tgt_ssn)
                self.snap_updates.append({'tgt_ssn': tgt_ssn, 'gno': gen_no, 'stime': time.time()})
        self._is_user_snap_sync_finished()
        for v in rep_volumes:
            vol_name = self.get_volume_name(v['id'])
            vol = self.client.search('volumes', name=vol_name)
            rvol_name = self.get_rep_name(vol_name)
            rvol = self.target.search('volumes', name=rvol_name)
            session_name = self.get_session_name(v['id'])
            rsession_name = self.get_rep_name(session_name)
            ssn = self.target.search('replication/sessions', name=rsession_name)
            if ssn.total:
                tgt_ssn = ssn.hits[0]
            ssn = self.client.search('replication/sessions', name=session_name)
            if ssn.total:
                src_ssn = ssn.hits[0]
            if (rvol.total and (src_ssn.state == 'in_sync') and (src_ssn.current_role == 'target')):
                src_ssn.state = 'failed_over'
                src_ssn.save()
                self._check_for_status(tgt_ssn, 'suspended')
                LOG.debug('The    target    session:    %s    state    is    changed    to    failed    over', session_name)
                src_ssn.state = 'in_sync'
                src_ssn.save()
                LOG.debug('The    target    session:    %s    state    is    changed    to    in    sync', session_name)
                rep_status = fields.ReplicationStatus.DISABLED
                volume_updates.append({'volume_id': v['id'], 'updates': {'replication_status': rep_status}})
        back_end_ip = self.configuration.san_ip
    else:
        'Failover    to    replication    target.'
        for v in volumes:
            vol_name = self.get_volume_name(v['id'])
            rv = self.get_rep_name(vol_name)
            if self.target.search('volumes', name=rv).total:
                self._failover_volume(v)
                volume_updates.append({'volume_id': v['id'], 'updates': {'replication_status': K2_REP_FAILED_OVER}})
            else:
                volume_updates.append({'volume_id': v['id'], 'updates': {'status': 'error'}})
        back_end_ip = self.replica.backend_id
    return (back_end_ip, volume_updates, [])
