Example: Join a machine to a site

This example shows how you can use the ArcGIS REST API to programmatically add a GIS server machine to an existing site. This consists of four parts:

  1. Getting an administrative token
  2. Joining the machine to the site
  3. Adding the machine to a cluster
  4. Starting the machine (This means that ArcGIS Server is made aware of the machine and can begin sending it requests.)

When working with a multiple-machine site, remember that the administrative token can only be used on the machine from which it is requested. Even though any machine in a site can receive a request, you need to structure your scripts so that all requests are made to the same machine that originally received the token request and returned the token.

# Demonstrates how to join a machine to a site
# For HTTP calls
import httplib, urllib, json
# For system tools
import sys, os
# For reading passwords without echoing
import getpass
# Defines the entry point into the script
def main(argv=None):
    # Print some info
    print
    print "This sample script joins a machine to a site"
    print
    
    # Ask for server name & site. Server name should be qualified in the format MACHINE.ESRI.COM
    serverName = raw_input("Enter name of machine that will join the site: ")
    targetHostName = raw_input("Enter name of machine already in target site: ")
    serverPort = 6080 
    targetSite = "http://" + targetHostName +  ":" + str(serverPort) + "/arcgis/admin" 
    targetCluster = raw_input("Enter the name of the cluster for the new machine (or leave blank for default): ")

    if targetCluster == "":
        targetCluster = "default"
    
    # Ask for an ArcGIS Server administrator user name and password
    username = raw_input("Enter ArcGIS Server site administrator username: ")
    password = getpass.getpass("Enter ArcGIS Server site administrator password: ")
    
    # Get a token
    token = getToken(username, password, targetHostName, serverPort)
    if token == "":
        print "Could not generate a token with the username and password provided."
        return
         
    #Join machine to site
    joinedSuccess = joinMachineToSite (targetSite, serverName, serverPort, username, password)
    if joinedSuccess == False:
        print "Failed to join " + serverName + " to site"
        return
    
    #Add machine to cluster
    addToClusterSuccess = addMachineToCluster(targetCluster, targetHostName, serverName, serverPort, token)
    if addToClusterSuccess == False:
        print "Failed to add " + serverName + " to cluster"
        return
    
    #Start machine
    startMachineSuccess = startMachine(targetHostName, serverPort, token)
    if startMachineSuccess == False:
        print "Failed to start " + serverName 
        return


# A function that joins a machine to a site
def joinMachineToSite(targetSite, joiningMachine, port, username, password):
    
    # Construct URL to create a new site
    joinSiteURL = "/arcgis/admin/joinSite"
    
    # Set up parameters for the request
    params = urllib.urlencode({'username': username, 'password': password, 'adminURL': targetSite, 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters    
    httpConn = httplib.HTTPConnection(joiningMachine, port)
    httpConn.request("POST", joinSiteURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while joining the machine to the site."
        return False
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):          
            print "Error returned by operation. " + str(data)
            return False
        else:
            print "Success."
            return True

# A function that adds a machine to a cluster
def addMachineToCluster(targetCluster, siteServer, machineToAdd, port, token):
    
    # Construct URL to add machine to cluster
    addClusterURL = "/arcgis/admin/clusters/" + targetCluster + "/machines/add"
    
    # Set up parameters for the request
    params = urllib.urlencode({'token': token, 'machineNames':machineToAdd, 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters    
    httpConn = httplib.HTTPConnection(siteServer, port)
    httpConn.request("POST", addClusterURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while adding machine to the cluster."
        return False
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):          
            print "Error returned by operation. " + str(data)
            return False
        else:
            print "Success."
            return True
    
# A function that starts a machine
def startMachine(machineToStart, port, token):
    #return True
   
    # Construct URL to add machine to cluster
    startMachineURL = "/arcgis/admin/machines/" + machineToStart + "/start"
    
    # Set up parameters for the request
    params = urllib.urlencode({'token': token, 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters    
    httpConn = httplib.HTTPConnection(machineToStart, port)
    httpConn.request("POST", startMachineURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while starting the machine."
        return False
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):          
            print "Error returned by operation. " + str(data)
            return False
        else:
            print "Success."
            return True

# A function to generate a token given username, password and the adminURL.
def getToken(username, password, serverName, serverPort):
    
    # Token URL is typically http://server[:port]/arcgis/admin/generateToken
    tokenURL = "/arcgis/admin/generateToken"
    
    # URL-encode the token parameters
    params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters
    httpConn = httplib.HTTPConnection(serverName, serverPort)
    httpConn.request("POST", tokenURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while fetching tokens from admin URL. Please check the URL and try again."
        return
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):            
            return
        
        # Extract the token from it
        token = json.loads(data)        
        return token['token']
    
# A function that checks that the input JSON object 
#  is not an error object.
def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        print "Error: JSON object returns an error. " + str(obj)
        return False
    else:
        return True
    
        
# Script start
if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
9/1/2015