# -*- coding: utf-8 -*-
import traceback
from utils.common.exception import FCDException
from utils.common.fic_base import TestCase
from utils.common.message import Message
import utils.common.log as logger
from plugins.DistributedStorage.scripts.logic.InstallOperate import InstallOperate
from plugins.DistributedStorage.scripts.logic.VMOperate import VMOperate


class InstallFSM(TestCase):
    def __init__(self, project_id, pod_id, fs_args, condition=None, metadata=None, **kwargs):
        super(InstallFSM, self).__init__(project_id, pod_id)
        self.operate = InstallOperate(self.project_id, self.pod_id, fs_args)
        self.vm_operate = VMOperate(self.project_id, self.pod_id, fs_args)
        self.float_ip = fs_args.get("float_ip")
        self.master_fsm = dict()
        self.standby_fsm = dict()
        self.condition = condition
        self.metadata = metadata
        self.more_args = kwargs
        self.is_manage = fs_args.get("is_manage", False)

    def procedure(self):
        try:
            logger.info("Start to install FSM.")
            # 获取FSM虚拟机所在的节点
            logger.info("Query vm info for install FSM.")
            self.master_fsm, self.standby_fsm = self.vm_operate.get_vm_data(self.pod_id, self.float_ip)
            master_fsm_ip = self.master_fsm.get('om_ip')
            master_fsm_user = self.master_fsm.get('user')
            master_fsm_passwd = self.master_fsm.get('passwd')
            master_fsm_root_pwd = self.master_fsm.get('root_pwd')
            standby_fsm_ip = self.standby_fsm.get('om_ip')
            standby_fsm_user = self.standby_fsm.get('user')
            standby_fsm_passwd = self.standby_fsm.get('passwd')
            standby_fsm_root_pwd = self.standby_fsm.get('root_pwd')

            # 打开FSM root用户
            logger.info("Open root access.")
            self.operate.open_sys_root(master_fsm_ip, master_fsm_user, master_fsm_passwd, master_fsm_root_pwd)
            self.operate.open_sys_root(standby_fsm_ip, standby_fsm_user, standby_fsm_passwd, standby_fsm_root_pwd)

            self.general_ha_config_on_fsm_vm(master_fsm_ip, master_fsm_root_pwd,
                                             standby_fsm_ip, standby_fsm_root_pwd)

            # 2.上传安装包
            logger.info("Upload the fusionstorage installation package.")
            self.operate.upload_packet_to_host(master_fsm_ip, 'root', master_fsm_root_pwd)
            self.modify_resolve_file(master_fsm_ip, master_fsm_root_pwd,
                                     standby_fsm_ip, standby_fsm_root_pwd)
            # 3.执行FSM安装
            logger.info("Installing FSM")
            res = self.operate.install_fsm(master_fsm_ip, 'root', master_fsm_root_pwd)
            if 0 > str(res).find('last_cmd=0'):
                logger.error("Install FSM failed")
                master_err_detail = str(res).replace('\n', '')
                logger.error("Failed to install FSM.Detail:%s" % master_err_detail.replace('password', '******'))
                raise Exception("Failed to install FSM.Detail:%s" % master_err_detail)
            logger.info("Install FSM successful")

            self.close_os_first_login(master_fsm_ip, master_fsm_root_pwd,
                                      standby_fsm_ip, standby_fsm_root_pwd)

            # 关闭FSM root用户
            self.operate.close_sys_root(master_fsm_ip, master_fsm_user,
                                        master_fsm_passwd, master_fsm_root_pwd, True)
            self.operate.close_sys_root(standby_fsm_ip, standby_fsm_user,
                                        standby_fsm_passwd, standby_fsm_root_pwd, True)
            logger.info("Close root permision")
        except FCDException as e:
            logger.error(traceback.format_exc())
            raise e
        except Exception as e:
            logger.error(traceback.format_exc())
            raise e
        return Message()

    def cleanup(self):
        logger.info("Start to clean up FSM VM nodes.")
        logger.info("Query newly created vm info for clean up.")
        # 获取FSM虚拟机所在的节点
        self.master_fsm, self.standby_fsm = self.vm_operate.get_vm_data(self.pod_id, self.float_ip)
        master_fsm_ip = self.master_fsm.get('om_ip')
        standby_fsm_ip = self.standby_fsm.get('om_ip')

        # 打开FSM root用户
        logger.info("Open root access.")
        self.operate.open_sys_root(master_fsm_ip, self.master_fsm.get('user'), self.master_fsm.get('passwd'),
                                   self.master_fsm.get('root_pwd'))
        self.operate.open_sys_root(standby_fsm_ip, self.standby_fsm.get('user'), self.standby_fsm.get('passwd'),
                                   self.standby_fsm.get('root_pwd'))
        if not self.is_manage:
            master_res = self.operate.unmodify_resolv_file(master_fsm_ip, 'root', self.master_fsm.get('root_pwd'))
            if 0 > str(master_res).find('last_cmd=0'):
                logger.error("unannotate /etc/resolv.conf file in master node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))
            standby_res = self.operate.unmodify_resolv_file(standby_fsm_ip, 'root', self.standby_fsm.get('root_pwd'))
            if 0 > str(standby_res).find('last_cmd=0'):
                logger.error("unannotate /etc/resolv.conf file  in standby node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))
        clr_fail_list = dict()
        logger.info("Start to clean up master FSM VM nodes[%s]." % master_fsm_ip)
        res = self.operate.clear_fsm(master_fsm_ip, 'root', self.master_fsm.get('root_pwd'))
        if 0 > str(res).find('last_cmd=0'):
            master_err_detail = res.replace('\n', '')
            clr_fail_list[master_fsm_ip] = master_err_detail
            logger.error("Failed to clean up FSM node[%s].Please clean it by manually.Detail:%s" % (
                master_fsm_ip, master_err_detail))

        logger.info("Start to clean up standby FSM VM nodes[%s]." % standby_fsm_ip)
        res = self.operate.clear_fsm(standby_fsm_ip, 'root', self.standby_fsm.get('root_pwd'))
        if 0 > str(res).find('last_cmd=0'):
            standby_err_detail = res.replace('\n', '')
            clr_fail_list[standby_fsm_ip] = standby_err_detail
            logger.error("Failed to clean up FSM node[%s]. Please clean it by manually.Detail:%s" % (
                standby_fsm_ip, standby_err_detail))

        if len(clr_fail_list.keys()) > 0:
            err_msg = "Failed to clean up nodes%s. Please clean it by manually. Detail:%s" % (
                list(clr_fail_list.keys()), clr_fail_list)
            logger.error(err_msg)
            raise Exception(err_msg)
        return Message()

    def general_ha_config_on_fsm_vm(self, master_fsm_ip, master_fsm_root_pwd,
                                    standby_fsm_ip, standby_fsm_root_pwd):
        """
        修改主备fsmHA配置文件
        :param master_fsm_ip:
        :param master_fsm_root_pwd:
        :param standby_fsm_ip:
        :param standby_fsm_root_pwd:
        :return:
        """
        # 获取FSM网络信息
        logger.info("Query network info.")
        self.master_fsm['netport'] = self.operate.get_netport_of_ip(master_fsm_ip, 'root', master_fsm_root_pwd)
        self.master_fsm['netmask'], self.master_fsm['gateway'] = self.operate.get_gateway_and_netmask_of_ip(
            master_fsm_ip, 'root', master_fsm_root_pwd, self.master_fsm.get('netport'))
        self.standby_fsm['gateway'] = self.master_fsm.get('gateway')
        self.standby_fsm['netmask'] = self.master_fsm.get('netmask')
        self.standby_fsm['netport'] = self.master_fsm.get('netport')

        logger.info("Generate Installation configuration files.")
        self.operate.general_HAConfig_on_master(master_fsm_ip, 'root', master_fsm_root_pwd, self.master_fsm,
                                                self.standby_fsm)
        self.operate.general_HAConfig_on_standby(standby_fsm_ip, 'root', standby_fsm_root_pwd, self.master_fsm,
                                                 self.standby_fsm)

    def close_os_first_login(self, master_fsm_ip, master_fsm_root_pwd,
                             standby_fsm_ip, standby_fsm_root_pwd):
        """
        设置虚拟机最后一次修改密码时间
        :param master_fsm_ip:
        :param master_fsm_root_pwd:
        :param standby_fsm_ip:
        :param standby_fsm_root_pwd:
        :return:
        """
        res = self.operate.close_os_first_login(master_fsm_ip, 'root', master_fsm_root_pwd, 'dsware')
        if 0 > str(res).find('last_cmd=0'):
            logger.error("Install FSM failed")
            master_err_detail = str(res).replace('\n', '')
            logger.error("Failed to close dsware first login."
                         "Detail:%s" % master_err_detail.replace('password', '******'))
            raise Exception("Failed to close first login FSM.Detail:%s" % master_err_detail)
        res = self.operate.close_os_first_login(standby_fsm_ip, 'root', standby_fsm_root_pwd, 'dsware')
        if 0 > str(res).find('last_cmd=0'):
            logger.error("Install FSM failed")
            master_err_detail = str(res).replace('\n', '')
            logger.error("Failed to close dsware first login."
                         "Detail:%s" % master_err_detail.replace('password', '******'))
            raise Exception("Failed to close first login.Detail:%s" % master_err_detail)

    def modify_resolve_file(self, master_fsm_ip, master_fsm_root_pwd,
                            standby_fsm_ip, standby_fsm_root_pwd):
        if not self.is_manage:
            # 注释掉两个FSM 虚拟机节点上 /etc/resolv.conf 的配置 避免rpm等命令执行慢
            master_res = self.operate.modify_resolv_file(master_fsm_ip, 'root', master_fsm_root_pwd)
            if 0 > str(master_res).find('last_cmd=0'):
                logger.error("annotate /etc/resolv.conf file in master node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))
            standby_res = self.operate.modify_resolv_file(standby_fsm_ip, 'root', standby_fsm_root_pwd)
            if 0 > str(standby_res).find('last_cmd=0'):
                logger.error("annotate /etc/resolv.conf file  in standby node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))
