# addClusterMembers.py
# 20080705
# copyright (c), 2010, by Arthur Kevin McGrath
# All rights reserved



#
#
# createFirstClusterMember
#
def createFirstClusterMember( nameOfCluster, nodeName, serverName, joinReplicationDomain = 0, nodeGroupName = "DefaultNodeGroup", coreGroupName = "DefaultCoreGroup" ):
  """
Required for proper cluster member configuration.  This method
determines the core group and the node group that all members
of this cluster will be part of.
  """
  replicate = 'false'
  allClusters = AdminConfig.list( 'ServerCluster' ).splitlines()
  if len( allClusters ) < 1:
    print "There are no clusters named", nameOfCluster
    return

  thisCluster = ""
  for c in allClusters:
    if c.find( nameOfCluster ) > -1:
      break
  else:
    print "There are no clusters named", nameOfCluster
    return

  print "Adding first member " + nodeName + " / " + serverName + " to " + nameOfCluster
  if joinReplicationDomain != 0:
    replicate = 'true'
  print AdminTask.createClusterMember('[-clusterName ' + nameOfCluster +
        ' -memberConfig [-memberNode ' + nodeName + ' -memberName ' + serverName +
        ' -replicatorEntry ' + replicate   + '] ' +
        ' -firstMember[ -templateName default -nodeGroup ' + nodeGroupName +
        '  -coreGroup ' + coreGroupName + '   ] ' + ']')


#
# createAdditionalClusterMembers
#
def createAdditionalClusterMembers( nameOfCluster, listOfServerNames ):
  """
Adds cluster members to an existing cluster.  
REQUIRES:
  1. that all members be application servers AND
  2. that there already be at least one member of the cluster.
     (The first cluster member establishes:
        a. the type of server (application, proxy, etc)
        b. the node group each node in the cluster must belong to
        c. the core group each server in the cluster must belong to
None of the servers on the listOfServerNames may already exist.  This method will create them.
As long as the cluster has a replication domain, you may choose to include
any or all of your proposed new servers in that domain.
example
  The following adds three servers to an existing cluster.  One of the three servers
  will become part of an existing ReplicationDomain.  The other two will not
newClusterMembers = [ ( "node01","c01s01",1 ), ( "node01","c01s01",1 ), ( "node01","c01s01" ) ]
addClusterMembers( "clusterName", newClusterMembers )
parameters:
   nameOfCluster
       String - the name of the cluster to create
   listOfServerNames
       an array of tuples
       each tuple has:
           nodeName - (mandatory)
              String - the Node in which to create the server
           serverName - (mandatory)
              String - the for the newly created the server
           replicationDomain - (optional)
              boolean - should we create a replication domain
                        for the newly created server?
                        default value is false
  """
  allClusters = AdminConfig.list( 'ServerCluster' ).splitlines()
  if len( allClusters ) < 1:
    print "There are no clusters named", nameOfCluster
    return

  thisCluster = ""
  for c in allClusters:
    if c.find( nameOfCluster ) > -1:
      thisCluster = c
      break
  else:
    print "There are no clusters named", nameOfCluster
    return

  listOfProposedNewMemberServers = list( listOfServerNames )
  print "  . . . adding " + str( len(listOfProposedNewMemberServers) ) + " additional members to the " + nameOfCluster + " cluster"

  # add the rest of the cluster members
  for server in listOfProposedNewMemberServers:
    nodeName = server[0]
    serverName = server[1]
    replicate = "false"
    if len( server ) == 2:
      print AdminTask.createClusterMember('[-clusterName ' + nameOfCluster + ' -memberConfig [-memberNode ' + nodeName + ' -memberName ' + serverName  + ']]')
    if len( server ) == 3:
      # convert the ReplicationDomain parameter of our parameter list
      # into the 'true' or 'false' notation that AdminTask requires
      if server[2] == 0:
        replicate = "false"
      else:
        replicate = "true"
      print AdminTask.createClusterMember('[-clusterName ' + nameOfCluster + ' -memberConfig [-memberNode ' + nodeName + ' -memberName ' + serverName + ' -replicatorEntry ' + replicate + ']]')
  # whatFilesChanged()
  return



# common routines
# The methods that follow are NEVER expected to be called
# by code outside of this file



#convertListFromJACL()
#convert a JACL list into a Jython list
#This method is VERY limited in terms of what it can do!
#It is VERY simplistic.  It cannot handle nested JACL lists.
#parameters:
#    jaclList - a String that represents a JACL list
#returns:
#    a Python List
def convertListFromJACL( jaclList ):
  "list()\nconvert a JACL list into a Jython list\nparameters:\n    jaclList - a String that represents a JACL list\nreturns:\n    a Python List\n"
  result = []
  # remove outter square brackets
  x = jaclList.replace( '[',' ')
  x = x.replace( ']',' ')
  x = x.strip()
  
  # use a comma to separate items on the list
  x = x.replace(   ') ' ,  '),'   )
  for t in x.split( ',' ):
    result.append(t)
  
  return result



# whatFilesChanged
# Reports the configuration files that will be changed
# as a result of any code in this file
# The changes will take effect when you call AdminConfig.save()
def whatFilesChanged():
  print "The following congfiguration files have changes pending:"
  print AdminConfig.queryChanges()
  return




