Skip To Content

Example: Join a machine to a site

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

  1. Getting an administrative token.
  2. Joining the machine to the site.
  3. 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 = 6443 
    targetSite = "https://" + targetHostName +  ":" + str(serverPort) + "/arcgis/admin" 

    
    # 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

    
    #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 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:]))