#!/usr/bin/env python

# 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.


import sys, os, subprocess, errno, re, getopt

# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
# ---- We do this so cloud_utils can be looked up in the following order:
# ---- 1) Sources directory
# ---- 2) waf configured PYTHONDIR
# ---- 3) System Python path
for pythonpath in (
		"@PYTHONDIR@",
		os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
	):
		if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
# ---- End snippet of code ----
import cloud_utils
from cloud_utils import stderr

E_GENERIC= 1
E_NOKVM = 2
E_NODEFROUTE = 3
E_DHCP = 4
E_NOPERSISTENTNET = 5
E_NETRECONFIGFAILED = 6
E_VIRTRECONFIGFAILED = 7
E_FWRECONFIGFAILED = 8
E_CPRECONFIGFAILED = 9
E_CPFAILEDTOSTART = 10
E_NOFQDN = 11

def bail(errno=E_GENERIC,message=None,*args):
	if message: stderr(message,*args)
	stderr("Cloud Console Proxy setup aborted")
	sys.exit(errno)


#---------------- boilerplate for python 2.4 support 


# CENTOS does not have this -- we have to put this here
try:
	from subprocess import check_call
	from subprocess import CalledProcessError
except ImportError:
	def check_call(*popenargs, **kwargs):
		import subprocess
		retcode = subprocess.call(*popenargs, **kwargs)
		cmd = kwargs.get("args")
		if cmd is None: cmd = popenargs[0]
		if retcode: raise CalledProcessError(retcode, cmd)
		return retcode

	class CalledProcessError(Exception):
		def __init__(self, returncode, cmd):
			self.returncode = returncode ; self.cmd = cmd
		def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)

# ------------ end boilerplate -------------------------

def check_hostname(): return check_call(["hostname",'--fqdn'])

class Command:
	def __init__(self,name,parent=None):
		self.__name = name
		self.__parent = parent
	def __getattr__(self,name):
		if name == "_print": name = "print"
		return Command(name,self)
	def __call__(self,*args):
		cmd = self.__get_recursive_name() + list(args)
		#print "	",cmd
		popen = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
		m = popen.communicate()
		ret = popen.wait()
		if ret:
			e = CalledProcessError(ret,cmd)
			e.stdout,e.stderr = m
			raise e
		class CommandOutput:
			def __init__(self,stdout,stderr):
				self.stdout = stdout
				self.stderr = stderr
		return CommandOutput(*m)
	def __lt__(self,other):
		cmd = self.__get_recursive_name()
		#print "	",cmd,"<",other
		popen = subprocess.Popen(cmd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
		m = popen.communicate(other)
		ret = popen.wait()
		if ret:
			e = CalledProcessError(ret,cmd)
			e.stdout,e.stderr = m
			raise e
		class CommandOutput:
			def __init__(self,stdout,stderr):
				self.stdout = stdout
				self.stderr = stderr
		return CommandOutput(*m)
		
	def __get_recursive_name(self,sep=None):
		m = self
		l = []
		while m is not None:
			l.append(m.__name)
			m = m.__parent
		l.reverse()
		if sep: return sep.join(l)
		else: return l
	def __str__(self):
		return '<Command %r>'%self.__get_recursive_name(sep=" ")
		
	def __repr__(self): return self.__str__()

ip = Command("ip")
service = Command("service")
chkconfig = Command("chkconfig")
ufw = Command("ufw")
iptables = Command("iptables")
augtool = Command("augtool")
ifconfig = Command("ifconfig")
uuidgen = Command("uuidgen")

Fedora = os.path.exists("/etc/fedora-release")
CentOS = os.path.exists("/etc/centos-release") or ( os.path.exists("/etc/redhat-release") and not os.path.exists("/etc/fedora-release") )

#--------------- procedure starts here ------------

def main():
	# parse cmd line	
	opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod="])
	host=None
	zone=None
	pod=None
    	autoMode=False
	do_check_kvm = True	
	for opt, arg in opts:
		if opt == "--host":
			if arg != "":
				host = arg
		elif opt == "--zone":
			if arg != "":
				zone = arg
		elif opt == "--pod":
		        if arg != "":
				pod = arg
        	elif opt == "-a":
            		autoMode=True
	servicename = "@PACKAGE@-console-proxy"
	
	if autoMode:
		cloud_utils.setLogFile("/var/log/cloud/setupConsoleProxy.log")

	stderr("Welcome to the Cloud Console Proxy setup")
	stderr("")

	try:
		check_hostname()
		stderr("The hostname of this machine is properly set up")
	except CalledProcessError,e:
		bail(E_NOFQDN,"This machine does not have an FQDN (fully-qualified domain name) for a hostname")

	stderr("Stopping the Cloud Console Proxy")
	cloud_utils.stop_service(servicename)
	stderr("Cloud Console Proxy stopped")

	ports = "8002".split()
	if Fedora or CentOS:
		try:
			o = chkconfig("--list","iptables")
			if ":on" in o.stdout and os.path.exists("/etc/sysconfig/iptables"):
				stderr("Setting up firewall rules to permit traffic to Cloud services")
				service.iptables.start() ; print o.stdout + o.stderr
				for p in ports: iptables("-I","INPUT","1","-p","tcp","--dport",p,'-j','ACCEPT')
				o = service.iptables.save() ; print o.stdout + o.stderr
		except CalledProcessError,e:
			print e.stdout+e.stderr
			bail(E_FWRECONFIGFAILED,"Firewall rules could not be set")
	else:
		stderr("Setting up firewall rules to permit traffic to Cloud services")
		try:
			for p in ports: ufw.allow(p)
			stderr("Rules set")
		except CalledProcessError,e:
			print e.stdout+e.stderr
			bail(E_FWRECONFIGFAILED,"Firewall rules could not be set")

		stderr("We are going to enable ufw now.  This may disrupt network connectivity and service availability.  See the ufw documentation for information on how to manage ufw firewall policies.")
		try:
			o = ufw.enable < "y\n" ; print o.stdout + o.stderr
		except CalledProcessError,e:
			print e.stdout+e.stderr
			bail(E_FWRECONFIGFAILED,"Firewall could not be enabled")

	cloud_utils.setup_consoleproxy_config("@CPSYSCONFDIR@/agent.properties", host, zone, pod)
	stderr("Enabling and starting the Cloud Console Proxy")
	cloud_utils.enable_service(servicename)
	stderr("Cloud Console Proxy restarted")

if __name__ == "__main__":
	main()

# FIXMES: 1) nullify networkmanager on ubuntu (asking the user first) and enable the networking service permanently
