#!/usr/bin/env python

# get client properties for bacula

import logging
import subprocess
import time
import json
from pprint import pprint

opsi={
    'server': "https://opsi.joergs.dass-it:4447/rpc",
    'username': "joergs",
    'password': "linuxlinux",
    }

catalog="MyCatalog"    
    
# "-d"
opsiCallPrefix=[ "opsi-admin",  "-a", opsi['server'], "-u", opsi['username'], "-p", opsi['password'] ]

opsiCallClientsWithBacula=[ "method", "productOnClient_getObjects", "[]", '{"productId":"bacula", "installationStatus": "installed"}']

opsiCallClientBaculaProperties=[ "method", "getProductProperties_hash", "bacula" ]


def write_client_conf( fd, client, properties ):
    #Client {
    #Name = ting-fd
    #Address = ting.dass-it
    #FDPort = 9102
    #Catalog = MyCatalog
    #Password = "D5w2V5w6B8a9H5Z"
    #File Retention = 6 months
    #Job Retention = 6 months
    #AutoPrune = yes
    #}
    params = [ "FDPort", "Catalog", "FileRetention", "JobRetention", "AutoPrune" ]
    fd.write( "Client {\n" )
    fd.write( "  Name     = " + properties['filedaemon_full_name'] + "\n" )
    fd.write( "  Address  = " + client['clientId'] + "\n" )
    # ipAddress: method host_getObjects [] '{"id":client['clientId']}'
    #print "  # Address =", ipAddress
    fd.write( "  Password = " + properties['filedaemon_full_password'] + "\n" )
    fd.write( "  Catalog  = " + catalog + "\n" )
    for i in params:
        try:
            fd.write( " " + i + " = " + properties[i.lower()] + "\n" )
        except KeyError:
            fd.write( "  # " + i + " = "  + "\n" )
    fd.write( "}\n")
    fd.write( "\n" )
    
    


def write_job_conf( fd, client, properties ):
    #Job {
    #FileSet = "tingfileset"
    #Name = "ting"
    #Client = ting-fd
    #JobDefs = "LaptopJob"
    ## Write Bootstrap = "/var/lib/bacula/ting.bsr"
    #}
    params = [ "Fileset", "JobDefs" ]
    fd.write( "Job {" + "\n" )
    fd.write( "  Name    = " + client['clientId'] + "-job" + "\n" )
    fd.write( "  Client  = " + properties['filedaemon_full_name'] + "\n" )
    for i in params:
        fd.write( "  " )
        try:
            if not properties[i.lower()]:
                fd.write( "# " )
            fd.write( i + " = " + properties[i.lower()] + "\n" )
        except KeyError:
            fd.write( "# " + i + " = " + "\n" )
    fd.write( "}" + "\n" )
    fd.write( "\n" )

#
# main
#

#logging.basicConfig(format='%(asctime)s %(levelname)8s %(message)s')
logging.basicConfig(format='%(message)s')
logger = logging.getLogger(__name__)
#logger.setLevel(logging.INFO)
logger.setLevel(logging.DEBUG)

logger.debug( "start" )

try:
    clientsWithBacula=json.loads( subprocess.check_output( opsiCallPrefix + opsiCallClientsWithBacula ) )
#except subprocess.CalledProcessError as e:
except BaseException as e:
    logger.exception( "failed: %s" %(e) )
    exit(1)

#pprint( clientsWithBacula )

if clientsWithBacula:
    try:
        file_opsi_clients = open('opsi-clients-generated.conf', 'w')
        file_opsi_clients.write( "#\n" )
        file_opsi_clients.write( "# automatically generated at {}\n".format( time.asctime() ) )
        file_opsi_clients.write( "#\n\n" )
        
        file_opsi_jobs = open('opsi-jobs-generated.conf', 'w')
        file_opsi_jobs.write( "#\n" )
        file_opsi_jobs.write( "# automatically generated at {}\n".format( time.asctime() ) )
        file_opsi_jobs.write( "#\n\n" )
    except BaseException as e:        
        logger.exception( "failed to create files" )
        exit(1)

for client in clientsWithBacula:
    clientId = client['clientId']
    
    try:
        clientBaculaProperties=json.loads( subprocess.check_output( opsiCallPrefix + opsiCallClientBaculaProperties + [ client['clientId'] ] ) )
    except ValueError as e:
        logger.warn( "%s: no valid information found: %s" %(clientId, e) )
    except subprocess.CalledProcessError as e:
        logger.exception( "%s: failed:" %(clientId) )
        #exit( 1 )
    else:            
        #pprint( clientBaculaProperties )
        write_client_conf( file_opsi_clients, client, clientBaculaProperties )
        write_job_conf( file_opsi_jobs, client, clientBaculaProperties )
        logger.info( "%s: OK" % clientId )

logger.debug( "finished" )
