# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
from utilities import writeProgressBar, bash
from cloudException import CloudRuntimeException, CloudInternalException, formatExceptionInfo
import logging
from networkConfig import networkConfig
import re
from configFileOps import configFileOps
import os
import shutil

class serviceCfgBase(object):
    def __init__(self, syscfg):
        self.status = None
        self.serviceName = ""
        self.cfoHandlers = []
        self.syscfg = syscfg
        self.netMgrRunning = False

    def configration(self):
        writeProgressBar("Configure " + self.serviceName + " ...", None)
        result = False
        try:
            result = self.config()
            if result is None:
                result = False

            self.status = result
            writeProgressBar(None, result)
            return result
        except CloudRuntimeException, e:
            self.status = result
            writeProgressBar(None, result)
            logging.debug(e.getDetails())
            raise e
        except CloudInternalException, e:
            self.status = result
            writeProgressBar(None, result)
            raise e
        except:
            logging.debug(formatExceptionInfo())
            if self.syscfg.env.mode == "Server":
                raise CloudRuntimeException("Configure %s failed, Please check the /var/log/cloudstack/setupManagement.log for detail"%self.serviceName)
            else:
                raise CloudRuntimeException("Configure %s failed, Please check the /var/log/cloudstack/agent/setup.log for detail"%self.serviceName)

    def backup(self):
        if self.status is None:
            return True

        writeProgressBar("Restore " + self.serviceName + " ...", None)
        result = False
        try:
            for cfo in self.cfoHandlers:
                cfo.backup()

            result = self.restore()
        except (CloudRuntimeException, CloudInternalException), e:
            logging.debug(e)

        writeProgressBar(None, result)

    def config(self):
        return True

    def restore(self):
        return True

class networkConfigBase:
    def __init__(self, syscfg):
        self.netcfg = networkConfig()
        self.serviceName = "Network"
        self.brName = None
        self.dev = None
        self.syscfg = syscfg

    def isPreConfiged(self):
        preCfged = False
        for br in self.syscfg.env.nics:
            if not self.netcfg.isNetworkDev(br):
                logging.debug("%s is not a network device, is it down?"%br)
                return False
            if self.syscfg.env.bridgeType == "openvswitch" and not self.netcfg.isOvsBridge(br):
                raise CloudInternalException("%s is not an openvswitch bridge" % br)
            if self.syscfg.env.bridgeType == "native" and not self.netcfg.isBridge(br) and not self.netcfg.isNetworkDev(br):
                # traffic label doesn't have to be a bridge, we'll create bridges on it
                raise CloudInternalException("%s is not a bridge and not a net device" % br)
            preCfged = True

        return preCfged

    def cfgNetwork(self, dev=None, brName=None):
        if dev is None:
            device = self.netcfg.getDefaultNetwork()
        else:
            device = self.netcfg.getDevInfo(dev)

        if device.type == "dev":
            if brName is None:
                brName = "cloudbr0"

            self.writeToCfgFile(brName, device)
        elif device.type == "brport":
            brName = self.netcfg.getBridge(dev)
            brDevice = self.netcfg.getDevInfo(brName)
            self.writeToCfgFile(brDevice.name, device)
        elif device.type == "bridge":
            #Fixme, assuming the outgoing physcial device is on port 1
            enslavedDev = self.netcfg.getEnslavedDev(device.name, 1)
            if enslavedDev is None:
                raise CloudInternalException("Failed to get enslaved devices on bridge:%s"%device.name)

            brDevice = device
            device = self.netcfg.getDevInfo(enslavedDev)
            brName = brDevice.name
            self.writeToCfgFile(brName, device)

        self.brName = brName
        self.dev = device.name

    def writeToCfgFile(self):
        pass

class networkConfigUbuntu(serviceCfgBase, networkConfigBase):
    def __init__(self, syscfg):
        super(networkConfigUbuntu, self).__init__(syscfg)
        networkConfigBase.__init__(self, syscfg)
        self.netCfgFile = "/etc/network/interfaces"

    def getNetworkMethod(self, line):
        if line.find("static") != -1:
            return "static"
        elif line.find("dhcp") != -1:
            return "dhcp"
        else:
            logging.debug("Failed to find the network method from:%s"%line)
            raise CloudInternalException("Failed to find the network method from /etc/network/interfaces")

    def addBridge(self, br, dev):
        bash("ifdown %s"%dev.name)
        for line in file(self.netCfgFile).readlines():
            match = re.match("^ *iface %s.*"%dev.name, line)
            if match is not None:
                dev.method = self.getNetworkMethod(match.group(0))
                cfo = configFileOps(self.netCfgFile, self)
                if self.syscfg.env.bridgeType == "openvswitch":
                    bridgeCfg = "\n".join(("",
                        "iface {device} inet manual",
                        "  ovs_type OVSPort",
                        "  ovs_bridge {bridge}",
                        "",
                        "auto {bridge}",
                        "allow-ovs {bridge}",
                        "iface {bridge} inet {device_method}",
                        "  ovs_type OVSBridge",
                        "  ovs_ports {device}",
                        "")).format(bridge=br, device=dev.name, device_method=dev.method)
                    cfo.replace_line("^ *auto %s.*" % dev.name,
                        "allow-{bridge} {device}".format(bridge=br, device=dev.name))
                elif self.syscfg.env.bridgeType == "native":
                    bridgeCfg = "\niface %s inet manual\n \
                                 auto %s\n \
                                 iface %s inet %s\n \
                                 bridge_ports %s\n"%(dev.name, br, br, dev.method, dev.name)
                else:
                    raise CloudInternalException("Unknown network.bridge.type %s" % self.syscfg.env.bridgeType)
                cfo.replace_line("^ *iface %s.*"%dev.name, bridgeCfg)

    def addDev(self, br, dev):
        logging.debug("Haven't implement yet")

    def addBridgeAndDev(self, br, dev):
        logging.debug("Haven't implement yet")

    def writeToCfgFile(self, br, dev):
        cfg = file(self.netCfgFile).read()
        ifaceDev = re.search("^ *iface %s.*"%dev.name, cfg, re.MULTILINE)
        ifaceBr = re.search("^ *iface %s.*"%br, cfg, re.MULTILINE)
        if ifaceDev is not None and ifaceBr is not None:
            logging.debug("%s:%s already configured"%(br, dev.name))
            return True
        elif ifaceDev is not None and ifaceBr is None:
            #reconfig bridge
            self.addBridge(br, dev)
        elif ifaceDev is None and ifaceBr is not None:
            #reconfig dev
            raise CloudInternalException("Missing device configuration, Need to add your network configuration into /etc/network/interfaces at first")
        else:
            raise CloudInternalException("Missing bridge/device network configuration, need to add your network configuration into /etc/network/interfaces at first")

    def config(self):
        try:
            if super(networkConfigUbuntu, self).isPreConfiged():
                return True

            self.netMgrRunning = self.syscfg.svo.isServiceRunning("network-manager")
            super(networkConfigUbuntu, self).cfgNetwork()
            if self.netMgrRunning:
                self.syscfg.svo.stopService("network-manager")
                self.syscfg.svo.disableService("network-manager")

            ifup_op = bash("ifup %s"%self.brName)
            if not ifup_op.isSuccess():
                raise CloudInternalException("Can't start network:%s %s" % (self.brName, ifup_op.getErrMsg()))

            self.syscfg.env.nics.append(self.brName)
            self.syscfg.env.nics.append(self.brName)
            self.syscfg.env.nics.append(self.brName)
            return True
        except:
            raise

    def restore(self):
        try:
            if self.netMgrRunning:
                self.syscfg.svo.enableService("network-manager")
                self.syscfg.svo.startService("network-manager")

            bash("/etc/init.d/networking stop")
            bash("/etc/init.d/networking start")
            return True
        except:
            logging.debug(formatExceptionInfo())
            return False

class networkConfigRedhat(serviceCfgBase, networkConfigBase):
    def __init__(self, syscfg):
        super(networkConfigRedhat, self).__init__(syscfg)
        networkConfigBase.__init__(self, syscfg)

    def writeToCfgFile(self, brName, dev):
        self.devCfgFile = "/etc/sysconfig/network-scripts/ifcfg-%s" % dev.name
        self.brCfgFile = "/etc/sysconfig/network-scripts/ifcfg-%s" % brName

        isDevExist = os.path.exists(self.devCfgFile)
        isBrExist = os.path.exists(self.brCfgFile)
        if isDevExist and isBrExist:
            logging.debug("%s:%s already configured"%(brName, dev.name))
            return True
        elif isDevExist and not isBrExist:
            #reconfig bridge
            self.addBridge(brName, dev)
        elif not isDevExist and isBrExist:
            #reconfig dev
            raise CloudInternalException("Missing device configuration, Need to add your network configuration into /etc/sysconfig/network-scripts at first")
        else:
            raise CloudInternalException("Missing bridge/device network configuration, need to add your network configuration into /etc/sysconfig/network-scripts at first")


    def addBridge(self, brName, dev):
        bash("ifdown %s" % dev.name)

        if not os.path.exists(self.brCfgFile):
            shutil.copy(self.devCfgFile, self.brCfgFile)

        #config device file at first: disable nm, set onboot=yes if not
        cfo = configFileOps(self.devCfgFile, self)
        cfo.addEntry("NM_CONTROLLED", "no")
        cfo.addEntry("ONBOOT", "yes")
        if self.syscfg.env.bridgeType == "openvswitch":
            if cfo.getEntry("IPADDR"):
                cfo.rmEntry("IPADDR", cfo.getEntry("IPADDR"))
            cfo.addEntry("DEVICETYPE", "ovs")
            cfo.addEntry("TYPE", "OVSPort")
            cfo.addEntry("OVS_BRIDGE", brName)
        elif self.syscfg.env.bridgeType == "native":
            cfo.addEntry("BRIDGE", brName)
        else:
            raise CloudInternalException("Unknown network.bridge.type %s" % self.syscfg.env.bridgeType)
        cfo.save()

        cfo = configFileOps(self.brCfgFile, self)
        cfo.addEntry("NM_CONTROLLED", "no")
        cfo.addEntry("ONBOOT", "yes")
        cfo.addEntry("DEVICE", brName)
        if self.syscfg.env.bridgeType == "openvswitch":
            if cfo.getEntry("HWADDR"):
                cfo.rmEntry("HWADDR", cfo.getEntry("HWADDR"))
            if cfo.getEntry("UUID"):
                cfo.rmEntry("UUID", cfo.getEntry("UUID"))
            cfo.addEntry("STP", "yes")
            cfo.addEntry("DEVICETYPE", "ovs")
            cfo.addEntry("TYPE", "OVSBridge")
        elif self.syscfg.env.bridgeType == "native":
            cfo.addEntry("TYPE", "Bridge")
        else:
            raise CloudInternalException("Unknown network.bridge.type %s" % self.syscfg.env.bridgeType)
        cfo.save()

    def config(self):
        try:
            if super(networkConfigRedhat, self).isPreConfiged():
                return True

            super(networkConfigRedhat, self).cfgNetwork()

            self.netMgrRunning = self.syscfg.svo.isServiceRunning("NetworkManager")
            if self.netMgrRunning:
                self.syscfg.svo.stopService("NetworkManager")
                self.syscfg.svo.disableService("NetworkManager")

            cfo = configFileOps("/etc/sysconfig/network", self)
            cfo.addEntry("NOZEROCONF", "yes")
            cfo.save()

            if not bash("service network restart").isSuccess():
                raise CloudInternalException("Can't restart network")

            self.syscfg.env.nics.append(self.brName)
            self.syscfg.env.nics.append(self.brName)
            self.syscfg.env.nics.append(self.brName)
            return True
        except:
            raise

    def restore(self):
        try:
            if self.netMgrRunning:
                self.syscfg.svo.enableService("NetworkManager")
                self.syscfg.svo.startService("NetworkManager")
            bash("service network restart")
            return True
        except:
            logging.debug(formatExceptionInfo())
            return False

class cgroupConfig(serviceCfgBase):
    def __init__(self, syscfg):
        super(cgroupConfig, self).__init__(syscfg)
        self.serviceName = "Cgroup"

    def config(self):
        try:
            cfo = configFileOps("/etc/cgconfig.conf", self)
            addConfig = "group virt {\n \
                            cpu {\n \
                                cpu.shares = 9216;\n \
                            }\n \
                        }\n"
            cfo.add_lines(addConfig)

            self.syscfg.svo.stopService("cgconfig", True)
            self.syscfg.svo.enableService("cgconfig",forcestart=True)

            cfo = configFileOps("/etc/cgrules.conf", self)
            cfgline = "root:/usr/sbin/libvirtd  cpu virt/\n"
            cfo.add_lines(cfgline)

            self.syscfg.svo.stopService("cgred", True)
            if not self.syscfg.svo.enableService("cgred"):
                return False
            return True
        except:
            raise

    def restore(self):
        try:
            self.syscfg.svo.stopService("cgconfig")
            self.syscfg.svo.enableService("cgconfig",forcestart=True)
            self.syscfg.svo.stopService("cgred")
            self.syscfg.svo.enableService("cgred")
            return True
        except:
            logging.debug(formatExceptionInfo())
            return False

class nfsConfig(serviceCfgBase):
    def __init__(self, syscfg):
        super(nfsConfig, self).__init__(syscfg)
        self.serviceName = "Nfs"

    def config(self):
        try:
            if not os.path.exists("/etc/nfsmount.conf"):
                return True

            cfo = configFileOps("/etc/nfsmount.conf")
            cfo.addEntry("Ac", "False")
            cfo.addEntry("actimeo", "0")
            cfo.save()

            self.syscfg.svo.enableService("rpcbind")
            self.syscfg.svo.stopService("rpcbind")
            self.syscfg.svo.startService("rpcbind")

            self.syscfg.svo.enableService("nfs")
            self.syscfg.svo.stopService("nfs")
            self.syscfg.svo.startService("nfs")

            return True
        except:
            logging.debug(formatExceptionInfo())
            return False

class securityPolicyConfigUbuntu(serviceCfgBase):
    def __init__(self, syscfg):
        super(securityPolicyConfigUbuntu, self).__init__(syscfg)
        self.serviceName = "Apparmor"

    def config(self):
        try:
            cmd = bash("service apparmor status")
            if not cmd.isSuccess() or cmd.getStdout() == "":
                self.spRunning = False
                return True

            if not bash("apparmor_status |grep libvirt").isSuccess():
                return True

            bash("ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/")
            bash("ln -s /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper /etc/apparmor.d/disable/")
            bash("apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd")
            bash("apparmor_parser -R /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper")

            return True
        except:
            raise CloudRuntimeException("Failed to configure apparmor, please see the /var/log/cloudstack/agent/setup.log for detail, \
                                        or you can manually disable it before starting myCloud")

    def restore(self):
        try:
            self.syscfg.svo.enableService("apparmor")
            self.syscfg.svo.startService("apparmor")
            return True
        except:
            logging.debug(formatExceptionInfo())
            return False

class securityPolicyConfigRedhat(serviceCfgBase):
    def __init__(self, syscfg):
        super(securityPolicyConfigRedhat, self).__init__(syscfg)
        self.serviceName = "SElinux"

    def config(self):
        selinuxEnabled = True

        if not bash("selinuxenabled").isSuccess():
            selinuxEnabled = False

        if selinuxEnabled:
            try:
                bash("setenforce 0")
                cfo = configFileOps("/etc/selinux/config", self)
                cfo.replace_line("SELINUX=", "SELINUX=permissive")
                return True
            except:
                raise CloudRuntimeException("Failed to configure selinux, please see the /var/log/cloudstack/agent/setup.log for detail, \
                                            or you can manually disable it before starting myCloud")
        else:
            return True

    def restore(self):
        try:
            bash("setenforce 1")
            return True
        except:
            logging.debug(formatExceptionInfo())
            return False

class libvirtConfigRedhat(serviceCfgBase):
    def __init__(self, syscfg):
        super(libvirtConfigRedhat, self).__init__(syscfg)
        self.serviceName = "Libvirt"

    def config(self):
        try:
            cfo = configFileOps("/etc/libvirt/libvirtd.conf", self)
            cfo.addEntry("listen_tcp", "1")
            cfo.addEntry("tcp_port", "\"16509\"")
            cfo.addEntry("auth_tcp", "\"none\"")
            cfo.addEntry("listen_tls", "0")
            cfo.save()

            cfo = configFileOps("/etc/sysconfig/libvirtd", self)
            cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'")
            cfo.addEntry("LIBVIRTD_ARGS", "-l")
            cfo.save()

            filename = "/etc/libvirt/qemu.conf"

            cfo = configFileOps(filename, self)
            cfo.addEntry("security_driver", "\"none\"")
            cfo.addEntry("user", "\"root\"")
            cfo.addEntry("group", "\"root\"")
            cfo.addEntry("vnc_listen", "\"0.0.0.0\"")
            cfo.save()

            self.syscfg.svo.stopService("libvirtd")
            if not self.syscfg.svo.startService("libvirtd"):
                return False

            return True
        except:
            raise

    def restore(self):
        pass

class libvirtConfigUbuntu(serviceCfgBase):
    def __init__(self, syscfg):
        super(libvirtConfigUbuntu, self).__init__(syscfg)
        self.serviceName = "Libvirt"

    def setupLiveMigration(self):
        cfo = configFileOps("/etc/libvirt/libvirtd.conf", self)
        cfo.addEntry("listen_tcp", "1")
        cfo.addEntry("tcp_port", "\"16509\"");
        cfo.addEntry("auth_tcp", "\"none\"");
        cfo.addEntry("listen_tls", "0")
        cfo.save()

        if os.path.exists("/etc/init/libvirt-bin.conf"):
            cfo = configFileOps("/etc/init/libvirt-bin.conf", self)
            cfo.replace_line("exec /usr/sbin/libvirtd","exec /usr/sbin/libvirtd -d -l")
        else:
            cfo = configFileOps("/etc/default/libvirt-bin", self)
            cfo.replace_or_add_line("libvirtd_opts=","libvirtd_opts='-l -d'")

    def config(self):
        try:
            self.setupLiveMigration()

            filename = "/etc/libvirt/qemu.conf"

            cfo = configFileOps(filename, self)
            cfo.addEntry("security_driver", "\"none\"")
            cfo.addEntry("user", "\"root\"")
            cfo.addEntry("group", "\"root\"")
            cfo.save()

            self.syscfg.svo.stopService("libvirt-bin")
            self.syscfg.svo.enableService("libvirt-bin")
            return True
        except:
            raise

    def restore(self):
        try:
            self.syscfg.svo.stopService("libvirt-bin")
            self.syscfg.svo.startService("libvirt-bin")
            return True
        except:
            logging.debug(formatExceptionInfo())
            return False

class firewallConfigUbuntu(serviceCfgBase):
    def __init__(self, syscfg):
        super(firewallConfigUbuntu, self).__init__(syscfg)
        self.serviceName = "Firewall"

    def config(self):
        try:
            ports = "22 1798 16509".split()
            for p in ports:
                bash("ufw allow %s"%p)
            bash("ufw allow proto tcp from any to any port 5900:6100")
            bash("ufw allow proto tcp from any to any port 49152:49216")
            self.syscfg.svo.stopService("ufw")
            self.syscfg.svo.startService("ufw")
            return True
        except:
            raise

    def restore(self):
        return True

class firewallConfigBase(serviceCfgBase):
    def __init__(self, syscfg):
        super(firewallConfigBase, self).__init__(syscfg)
        self.serviceName = "Firewall"
        self.rules = []

    def allowPort(self, port):
        status = False
        try:
            status = bash("iptables-save|grep INPUT|grep -w %s"%port).isSuccess()
        except:
            pass

        if not status:
            redo = False
            result = True
            try:
                result = bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port).isSuccess()
            except:
                redo = True

            if not result or redo:
                bash("sleep 30")
                bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port)

    def config(self):
        try:
            for port in self.ports:
                self.allowPort(port)

            for rule in self.rules:
                bash("iptables " + rule)

            bash("iptables-save > /etc/sysconfig/iptables")
            self.syscfg.svo.stopService("iptables")
            self.syscfg.svo.startService("iptables")
            return True
        except:
            raise

    def restore(self):
        return True

class firewallConfigAgent(firewallConfigBase):
    def __init__(self, syscfg):
        super(firewallConfigAgent, self).__init__(syscfg)
        self.ports = "22 16509 5900:6100 49152:49216".split()
        if syscfg.env.distribution.getVersion() == "CentOS":
            self.rules = ["-D FORWARD -j RH-Firewall-1-INPUT"]
        else:
            self.rules = ["-D FORWARD -j REJECT --reject-with icmp-host-prohibited"]


class cloudAgentConfig(serviceCfgBase):
    def __init__(self, syscfg):
        super(cloudAgentConfig, self).__init__(syscfg)
        if syscfg.env.agentMode == "Agent":
            self.serviceName = "cloudAgent"
        elif syscfg.env.agentMode == "myCloud":
            self.serviceName = "myCloud"
        elif syscfg.env.agentMode == "Console":
            self.serviceName = "Console Proxy"

    def configMyCloud(self):
        try:
            cfo = configFileOps("/etc/cloudstack/agent/agent.properties", self)
            cfo.addEntry("host", self.syscfg.env.mgtSvr)
            cfo.addEntry("zone", self.syscfg.env.zone)
            cfo.addEntry("port", "443")
            cfo.addEntry("private.network.device", self.syscfg.env.nics[0])
            cfo.addEntry("public.network.device", self.syscfg.env.nics[1])
            cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])
            if cfo.getEntry("local.storage.uuid") == "":
                cfo.addEntry("local.storage.uuid", str(bash("uuidgen").getStdout()))
            cfo.addEntry("guid", str(self.syscfg.env.uuid))
            cfo.addEntry("mount.path", "/mnt")
            cfo.addEntry("resource", "com.cloud.storage.resource.LocalSecondaryStorageResource|com.cloud.agent.resource.computing.CloudZonesComputingResource")
            cfo.save()

            #self.syscfg.svo.stopService("cloud-agent")
            #self.syscfg.svo.enableService("cloud-agent")
            return True
        except:
            raise

    def configAgent(self):
        try:
            cfo = configFileOps("/etc/cloudstack/agent/agent.properties", self)
            cfo.addEntry("host", self.syscfg.env.mgtSvr)
            cfo.addEntry("zone", self.syscfg.env.zone)
            cfo.addEntry("pod", self.syscfg.env.pod)
            cfo.addEntry("cluster", self.syscfg.env.cluster)
            cfo.addEntry("hypervisor.type", self.syscfg.env.hypervisor)
            cfo.addEntry("port", "8250")
            cfo.addEntry("private.network.device", self.syscfg.env.nics[0])
            cfo.addEntry("public.network.device", self.syscfg.env.nics[1])
            cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])
            cfo.addEntry("guid", str(self.syscfg.env.uuid))
            if cfo.getEntry("local.storage.uuid") == "":
                cfo.addEntry("local.storage.uuid", str(bash("uuidgen").getStdout()))
            cfo.addEntry("resource", "com.cloud.hypervisor.kvm.resource.LibvirtComputingResource")
            cfo.save()

            self.syscfg.svo.stopService("cloudstack-agent")
            bash("sleep 30")
            self.syscfg.svo.enableService("cloudstack-agent")
            return True
        except:
            raise

    def configConsole(self):
        try:
            cfo = configFileOps("/etc/cloudstack/agent/agent.properties", self)
            cfo.addEntry("host", self.syscfg.env.mgtSvr)
            cfo.addEntry("zone", self.syscfg.env.zone)
            cfo.addEntry("pod", self.syscfg.env.pod)
            cfo.addEntry("cluster", self.syscfg.env.cluster)
            cfo.addEntry("port", "8250")
            cfo.addEntry("private.network.device", self.syscfg.env.nics[0])
            cfo.addEntry("public.network.device", self.syscfg.env.nics[1])
            cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])
            cfo.addEntry("guid", str(self.syscfg.env.uuid))
            cfo.addEntry("resource", "com.cloud.agent.resource.computing.consoleProxyResource")
            cfo.save()

            self.syscfg.svo.stopService("cloudstack-agent")
            self.syscfg.svo.enableService("cloudstack-agent")
            return True
        except:
            raise

    def config(self):
        if self.syscfg.env.agentMode == "Agent":
            return self.configAgent()
        elif self.syscfg.env.agentMode == "myCloud":
            return self.configMyCloud()
        elif self.syscfg.env.agentMode == "console":
            return self.configConsole()

    def restore(self):
        return True


class sudoersConfig(serviceCfgBase):
    def __init__(self, syscfg):
        super(sudoersConfig, self).__init__(syscfg)
        self.serviceName = "sudoers"
    def config(self):
        try:
            cfo = configFileOps("/etc/sudoers", self)
            cfo.addEntry("cloud ALL ", "NOPASSWD : /bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount, /usr/bin/keytool")
            cfo.rmEntry("Defaults", "requiretty", " ")
            cfo.save()
            return True
        except:
            raise

    def restore(self):
        return True

class firewallConfigServer(firewallConfigBase):
    def __init__(self, syscfg):
        super(firewallConfigServer, self).__init__(syscfg)
        #9090 is used for cluster management server
        if self.syscfg.env.svrMode == "myCloud":
            self.ports = "443 8080 8250 8443 9090".split()
        else:
            self.ports = "8080 7080 8250 9090".split()

class ubuntuFirewallConfigServer(firewallConfigServer):
    def allowPort(self, port):
        status = False
        try:
            status = bash("iptables-save|grep INPUT|grep -w %s"%port).isSuccess()
        except:
            pass

        if not status:
            bash("ufw allow %s/tcp"%port)

    def config(self):
        try:
            for port in self.ports:
                self.allowPort(port)

            return True
        except:
            raise
