# Copyright 2016 Mirantis Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import getpass
import logging

from cloudferry.lib.base import exception
from cloudferry.lib.base.action import action
from cloudferry.lib.utils import local
from cloudferry.lib.utils import remote_runner

LOG = logging.getLogger(__name__)


class CheckVMAXPrerequisites(action.Action):
    """This verifies prerequisites required for NFS to VMAX iSCSI cinder
    volume migration"""

    def _iscsiadm_is_installed_locally(self):
        LOG.info("Checking if iscsiadm tool is installed")
        try:
            local.run('iscsiadm --help &>/dev/null')
        except local.LocalExecutionFailed:
            msg = ("iscsiadm is not available on the local host. Please "
                   "install iscsiadm tool on the node you running on or "
                   "choose other cinder backend for migration. iscsiadm is "
                   "mandatory for migrations with EMC VMAX cinder backend")
            LOG.error(msg)
            raise exception.AbortMigrationError(msg)

    def _check_local_sudo_password_set(self):
        current_user = getpass.getuser()
        if current_user != 'root' and \
                self.cfg.migrate.local_sudo_password is None:
            try:
                local.sudo('ls')
            except local.LocalExecutionFailed:
                msg = ("CloudFerry is running as '{user}' user, but "
                       "passwordless sudo does not seem to be configured on "
                       "current host. Please either specify password in "
                       "`local_sudo_password` config option, or run "
                       "CloudFerry as root user.").format(user=current_user)
                LOG.error(msg)
                raise exception.AbortMigrationError(msg)

    def _ssh_connectivity_between_controllers(self):
        src_host = self.cfg.src.ssh_host
        src_user = self.cfg.src.ssh_user
        dst_host = self.cfg.dst.ssh_host
        dst_user = self.cfg.dst.ssh_user

        LOG.info("Checking ssh connectivity between '%s' and '%s'",
                 src_host, dst_host)

        rr = remote_runner.RemoteRunner(src_host, src_user)

        ssh_opts = ('-o UserKnownHostsFile=/dev/null '
                    '-o StrictHostKeyChecking=no')

        cmd = "ssh {opts} {user}@{host} 'echo ok'".format(opts=ssh_opts,
                                                          user=dst_user,
                                                          host=dst_host)

        try:
            rr.run(cmd)
        except remote_runner.RemoteExecutionError:
            msg = ("No ssh connectivity between source host '{src_host}' and "
                   "destination host '{dst_host}'. Make sure you have keys "
                   "and correct configuration on these nodes. To verify run "
                   "'{ssh_cmd}' from '{src_host}' node")
            msg = msg.format(src_host=src_host, dst_host=dst_host, ssh_cmd=cmd)
            LOG.error(msg)
            raise exception.AbortMigrationError(msg)

    def run(self, **kwargs):
        if self.cfg.dst_storage.backend != 'iscsi-vmax':
            return
        self._iscsiadm_is_installed_locally()
        self._ssh_connectivity_between_controllers()
        self._check_local_sudo_password_set()

[((23, 6, 23, 33), 'logging.getLogger', 'logging.getLogger', ({(23, 24, 23, 32): '__name__'}, {}), '(__name__)', False, 'import logging\n'), ((43, 23, 43, 40), 'getpass.getuser', 'getpass.getuser', ({}, {}), '()', False, 'import getpass\n'), ((66, 13, 66, 59), 'cloudferry.lib.utils.remote_runner.RemoteRunner', 'remote_runner.RemoteRunner', ({(66, 40, 66, 48): 'src_host', (66, 50, 66, 58): 'src_user'}, {}), '(src_host, src_user)', False, 'from cloudferry.lib.utils import remote_runner\n'), ((33, 12, 33, 52), 'cloudferry.lib.utils.local.run', 'local.run', ({(33, 22, 33, 51): '"""iscsiadm --help &>/dev/null"""'}, {}), "('iscsiadm --help &>/dev/null')", False, 'from cloudferry.lib.utils import local\n'), ((40, 18, 40, 52), 'cloudferry.lib.base.exception.AbortMigrationError', 'exception.AbortMigrationError', ({(40, 48, 40, 51): 'msg'}, {}), '(msg)', False, 'from cloudferry.lib.base import exception\n'), ((47, 16, 47, 32), 'cloudferry.lib.utils.local.sudo', 'local.sudo', ({(47, 27, 47, 31): '"""ls"""'}, {}), "('ls')", False, 'from cloudferry.lib.utils import local\n'), ((84, 18, 84, 52), 'cloudferry.lib.base.exception.AbortMigrationError', 'exception.AbortMigrationError', ({(84, 48, 84, 51): 'msg'}, {}), '(msg)', False, 'from cloudferry.lib.base import exception\n'), ((55, 22, 55, 56), 'cloudferry.lib.base.exception.AbortMigrationError', 'exception.AbortMigrationError', ({(55, 52, 55, 55): 'msg'}, {}), '(msg)', False, 'from cloudferry.lib.base import exception\n')]