#!/usr/bin/env groovy
/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2013. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/

import com.urbancode.air.AirPluginTool
import com.urbancode.air.XTrustProvider
import iControl.LocalLBLBMethod
import iControl.CommonIPPortDefinition
import iControl.LocalLBPoolLocator
import iControl.LocalLBPoolBindingStub
import iControl.LocalLBMonitorRule
import iControl.LocalLBMonitorRuleType
import iControl.LocalLBPoolMonitorAssociation
import iControl.CommonEnabledState
import iControl.LocalLBServiceDownAction
import iControl.ManagementPartitionBindingStub

final def apTool = new AirPluginTool(this.args[0], this.args[1])

final def props = apTool.getStepProperties()

final def serverUrlArray = props['serverURL']?.split('://') as String[]
final def username = props['username']
final def password = props['password']
final def timeout = Integer.parseInt(props['timeout'])

final def poolName = props['poolName']
final def partitionName = props['partition']
final def lbMethod = props['lbMethod']
final def monitorList = props['monitors']
final def allowSnat = props['allowSnat']
final def allowNat = props['allowNat']
final def serviceDownAction = props['serviceDownAction']
final def slowRampTime = props['slowRampTime']
final def clientIpTos = props['clientIpTos']
final def serverIpTos = props['serverIpTos']
final def clientLinkQos = props['clientLinkQos']
final def serverLinkQos = props['serverLinkQos']

try {
    if (serverUrlArray.length != 2) println("Malformed server URL: ${props['serverURL']} missing <protocol>://")
    if (serverUrlArray[1].endsWith('/')) serverUrlArray[1] = serverUrlArray[1].substring(0, serverUrlArray[1].length() - 1)

    final def connectionString = serverUrlArray[0] + "://" + username + ":" + password + "@" +
            serverUrlArray[1] + "/iControl/iControlPortal.cgi"

    XTrustProvider.install()
    
    iControl.ManagementPartitionBindingStub partition = (iControl.ManagementPartitionBindingStub)new iControl.ManagementPartitionLocator().getManagementPartitionPort(new java.net.URL(connectionString));
    partition.setTimeout(timeout * 1000)
    partition.set_active_partition(partitionName);
    
    def LocalLBPoolBindingStub poolStub

    def getState = {
        try {
            return poolStub.get_object_status([poolName] as String[])
        }
        catch (Exception e) {
            return null
        }
    }

    println("Connecting to server ${props['serverURL']} using timeout of $timeout second(s)")
    poolStub =
        new LocalLBPoolLocator().getLocalLBPoolPort(new java.net.URL(connectionString)) as LocalLBPoolBindingStub
    poolStub.setTimeout(timeout * 1000)

    def currentState = getState()

    if (currentState && currentState.length > 0) {
        println "Pool $poolName already exists. Setting load balancing method to $lbMethod ..."
        poolStub.set_lb_method(
                [poolName] as String[],
                [LocalLBLBMethod.fromString(lbMethod)] as LocalLBLBMethod[])
        println "Pool successfully updated!"

    }
    else {
        println "Creating $poolName with $lbMethod load balancing"
        poolStub.create(
                [poolName] as String[],
                [LocalLBLBMethod.fromString(lbMethod)] as LocalLBLBMethod[],
                new CommonIPPortDefinition[1][0])
        println "Pool successfully created!"
    }

    // now configure pool settings
    poolStub.remove_monitor_association([poolName] as String[])
    if (monitorList) {
        def monitorArray = monitorList.split('\n').join(',').split(',').findAll{ it && it.trim().size() > 0} as String[]
        monitorArray.each {it.trim()}
        println "Updating monitors to $monitorArray"
        def monitorAssociation
        def monitorRule = new LocalLBMonitorRule(
                                LocalLBMonitorRuleType.MONITOR_RULE_TYPE_SINGLE,
                                0,
                                monitorArray)
        poolStub.set_monitor_association(new LocalLBPoolMonitorAssociation(poolName, monitorRule))
        println "Pool monitors updated successfully!"
    }

    println "Update Allow SNAT to ${allowSnat}"
    poolStub.set_allow_snat_state([poolName] as String[], [CommonEnabledState.fromString(allowSnat)] as CommonEnabledState[])

    println "Update Allow NAT to ${allowNat}"
    poolStub.set_allow_nat_state([poolName] as String[], [CommonEnabledState.fromString(allowNat)] as CommonEnabledState[])

    println "Update Action On Service Down to ${serviceDownAction}"
    poolStub.set_action_on_service_down(
            [poolName] as String[],
            [LocalLBServiceDownAction.fromString(serviceDownAction)] as LocalLBServiceDownAction[])

    println "Update Slow Ramp Time to ${slowRampTime}"
    poolStub.set_slow_ramp_time(
            [poolName] as String[],
            [Long.parseLong(slowRampTime)] as long[])

    if (clientIpTos) {
        println "Update IP ToS to Client to ${clientIpTos}"
        poolStub.set_client_ip_tos(
                [poolName] as String[],
                [Long.parseLong(clientIpTos)] as long[])
    }

    if (serverIpTos) {
        println "Update IP ToS to Server to ${serverIpTos}"
        poolStub.set_server_ip_tos(
                [poolName] as String[],
                [Long.parseLong(serverIpTos)] as long[])
    }

    if (clientLinkQos) {
        println "Update QoS to Client to ${clientLinkQos}"
        poolStub.set_client_link_qos(
                [poolName] as String[],
                [Long.parseLong(clientLinkQos)] as long[])
    }

    if (serverLinkQos) {
        println "Update QoS to Server to ${serverLinkQos}"
        poolStub.set_server_link_qos(
                [poolName] as String[],
                [Long.parseLong(serverLinkQos)] as long[])
    }

}
catch (Exception e) {
    e.printStackTrace()
    System.exit(1)
}
